From 8f4d1026de4fdac693da5639e5c6f3f6753075fa Mon Sep 17 00:00:00 2001 From: Jim Winstead Date: Mon, 21 Sep 2009 15:20:14 -0700 Subject: [PATCH 001/157] The mysql command line client ignored the --skip-column-names option when used in conjunction with --vertical. (Bug #47147, patch by Harrison Fisk) --- client/mysql.cc | 3 ++- mysql-test/r/mysql.result | 11 ++++++++--- mysql-test/t/mysql.test | 5 +++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index bafd173343e..c579d0ccaaa 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -3510,7 +3510,8 @@ print_table_data_vertically(MYSQL_RES *result) for (uint off=0; off < mysql_num_fields(result); off++) { field= mysql_fetch_field(result); - tee_fprintf(PAGER, "%*s: ",(int) max_length,field->name); + if (column_names) + tee_fprintf(PAGER, "%*s: ",(int) max_length,field->name); if (cur[off]) { unsigned int i; diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index c02073df677..32917888b81 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -162,8 +162,8 @@ ERROR 1049 (42000) at line 1: Unknown database 'invalid' ERROR 1049 (42000) at line 1: Unknown database 'invalid' Test connect with dbname + hostname Test connect with dbname + _invalid_ hostname -ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'invalid_hostname' (errno) -ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'invalid_hostname' (errno) +ERROR 2003 (HY000) at line 1: Can't connect to MySQL server on 'invalid_hostname' (errno) +ERROR 2003 (HY000) at line 1: Can't connect to MySQL server on 'invalid_hostname' (errno) The commands reported in the bug report ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'cyril has found a bug :)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' (errno) Too long dbname @@ -198,7 +198,7 @@ COUNT (*) 1 COUNT (*) 1 -ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'invalid_hostname' (errno) +ERROR 2003 (HY000) at line 1: Can't connect to MySQL server on 'invalid_hostname' (errno) End of 5.0 tests WARNING: --server-arg option not supported in this configuration. Warning (Code 1286): Unknown table engine 'nonexistent' @@ -230,4 +230,9 @@ a: b drop table t1; +Bug #47147: mysql client option --skip-column-names does not apply to vertical output + +*************************** 1. row *************************** +1 + End of tests diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index cffa6392fa3..7b87ae10e59 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -401,5 +401,10 @@ insert into t1 values ('\0b\0'); --exec $MYSQL --xml test -e "select a from t1" drop table t1; +--echo +--echo Bug #47147: mysql client option --skip-column-names does not apply to vertical output +--echo +--exec $MYSQL --skip-column-names --vertical test -e "select 1 as a" + --echo --echo End of tests From 46ca22b093406d566d8f108f55111fc70b49af80 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Mon, 9 Nov 2009 17:36:13 +0000 Subject: [PATCH 002/157] BUG#48357: SHOW BINLOG EVENTS: Wrong offset or I/O error In function log_event.cc:Query_log_event::write, there was a cast that was triggering undefined behavior. The offending cast is the following: write_str_with_code_and_len((char **)(&start), catalog, catalog_len, Q_CATALOG_NZ_CODE); This results in calling write_str_with_code_and_len with first argument pointing to a (char **) while "start" is itself a pointer to uchar (uchar *). Inside write_str_with_..., the content of start is then be updated: (*dst)+= len; The instruction above would cause the (*dst) pointer (ie, the "start" argument, from the caller point of view, and which actually points to uchar instead of pointing to char) to be updated so that it would increment catalog_len. However, this seems to break strict-aliasing rules ultimately causing the increment and assignment to behave unexpectedly. We fix this by removing the cast and by making the types match. --- sql/log_event.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 2cb253c9c56..9a3c6537b9e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2138,8 +2138,8 @@ void Query_log_event::pack_info(Protocol *protocol) /** Utility function for the next method (Query_log_event::write()) . */ -static void write_str_with_code_and_len(char **dst, const char *src, - int len, uint code) +static void write_str_with_code_and_len(uchar **dst, const char *src, + uint len, uint code) { /* only 1 byte to store the length of catalog, so it should not @@ -2234,7 +2234,7 @@ bool Query_log_event::write(IO_CACHE* file) } if (catalog_len) // i.e. this var is inited (false for 4.0 events) { - write_str_with_code_and_len((char **)(&start), + write_str_with_code_and_len(&start, catalog, catalog_len, Q_CATALOG_NZ_CODE); /* In 5.0.x where x<4 masters we used to store the end zero here. This was @@ -2272,7 +2272,7 @@ bool Query_log_event::write(IO_CACHE* file) { /* In the TZ sys table, column Name is of length 64 so this should be ok */ DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH); - write_str_with_code_and_len((char **)(&start), + write_str_with_code_and_len(&start, time_zone_str, time_zone_len, Q_TIME_ZONE_CODE); } if (lc_time_names_number) From f1abd015dcec3c1347e96e6197db8fd05c021537 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Thu, 12 Nov 2009 17:10:19 +0200 Subject: [PATCH 003/157] Bug #47210 first execution of "start slave until" stops too early Until-pos guarding did not distiguish the master originated events from ones that the slave can introduce to the relay log e.g Rotate to the next relay log at slave restarting. The local Rotate's coordinate are incomparable with the Until-master-pos. That led to the unexpectable stop this bug describes. Fixed with to avoid Until-master-pos comparison for a local slave's event. Notice that if --replicate-same-server is true such event is treated as coming from the master side. mysql-test/r/rpl_until.result: results changed. mysql-test/t/rpl_until.test: regression test for bug#47210 is added. sql/slave.cc: st_relay_log_info::is_until_satisfied() is augmented with avoidance of Until-master-pos comparison for a local slave's event. if --replicate-same-server is true such event is treated as coming from the master side. sql/slave.h: signature of is_until_satisfied() changed to supply THD and Event to the routine. --- mysql-test/r/rpl_until.result | 28 +++++++++++++++ mysql-test/t/rpl_until.test | 65 ++++++++++++++++++++++++++++++++++- sql/slave.cc | 14 ++++---- sql/slave.h | 2 +- 4 files changed, 101 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/rpl_until.result b/mysql-test/r/rpl_until.result index 60b956785ba..3dac55ec5c1 100644 --- a/mysql-test/r/rpl_until.result +++ b/mysql-test/r/rpl_until.result @@ -194,3 +194,31 @@ start slave sql_thread; start slave until master_log_file='master-bin.000001', master_log_pos=776; Warnings: Note 1254 Slave is already running +include/stop_slave.inc +drop table if exists t1; +reset slave; +change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root'; +drop table if exists t1; +reset master; +create table t1 (a int primary key auto_increment); +start slave; +include/stop_slave.inc +master and slave are in sync now +select 0 as zero; +zero +0 +insert into t1 set a=null; +insert into t1 set a=null; +select count(*) as two from t1; +two +2 +start slave until master_log_file='master-bin.000001', master_log_pos= UNTIL_POS;; +slave stopped at the prescribed position +select 0 as zero; +zero +0 +select count(*) as one from t1; +one +1 +drop table t1; +start slave; diff --git a/mysql-test/t/rpl_until.test b/mysql-test/t/rpl_until.test index c404ea7e58b..abd78b6a005 100644 --- a/mysql-test/t/rpl_until.test +++ b/mysql-test/t/rpl_until.test @@ -84,4 +84,67 @@ start slave until relay_log_file='slave-relay-bin.000002', master_log_pos=561; start slave sql_thread; start slave until master_log_file='master-bin.000001', master_log_pos=776; -# End of 4.1 tests +# +# bug#47210 first execution of "start slave until" stops too early +# +# testing that a slave rotate event that is caused by stopping the slave +# does not intervene anymore in UNTIL condition. +# + +connection slave; +source include/stop_slave.inc; +--disable_warnings +drop table if exists t1; +--enable_warnings +reset slave; +--replace_result $MASTER_MYPORT MASTER_PORT +eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root'; + +connection master; +--disable_warnings +drop table if exists t1; +--enable_warnings +reset master; +create table t1 (a int primary key auto_increment); +save_master_pos; +let $master_pos= query_get_value(SHOW MASTER STATUS, Position, 1); + +connection slave; +start slave; +sync_with_master; + +# at this point slave will close the relay log stamping it with its own +# Rotate log event. This event won't be examined on matter of the master +# UNTIL pos anymore. +source include/stop_slave.inc; +let $slave_exec_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); + +--echo master and slave are in sync now +let $diff_pos= `select $master_pos - $slave_exec_pos`; +eval select $diff_pos as zero; + +connection master; +insert into t1 set a=null; +let $until_pos= query_get_value(SHOW MASTER STATUS, Position, 1); +insert into t1 set a=null; +select count(*) as two from t1; + +connection slave; +--replace_result $until_pos UNTIL_POS; +eval start slave until master_log_file='master-bin.000001', master_log_pos= $until_pos; +source include/wait_for_slave_sql_to_stop.inc; +let $slave_exec_pos= query_get_value(SHOW SLAVE STATUS, Exec_Master_Log_Pos, 1); +--echo slave stopped at the prescribed position +let $diff_pos= `select $until_pos - $slave_exec_pos`; +eval select $diff_pos as zero; +select count(*) as one from t1; + + +connection master; +drop table t1; + +connection slave; +start slave; +sync_with_master; + +# End of tests diff --git a/sql/slave.cc b/sql/slave.cc index dd29a3f45c9..87bd7e2be8c 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3223,7 +3223,7 @@ int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int expected_error) false - condition not met */ -bool st_relay_log_info::is_until_satisfied(my_off_t master_beg_pos) +bool st_relay_log_info::is_until_satisfied(THD *thd, Log_event *ev) { const char *log_name; ulonglong log_pos; @@ -3232,8 +3232,12 @@ bool st_relay_log_info::is_until_satisfied(my_off_t master_beg_pos) if (until_condition == UNTIL_MASTER_POS) { + if (ev && ev->server_id == (uint32) ::server_id && !replicate_same_server_id) + return FALSE; log_name= group_master_log_name; - log_pos= master_beg_pos; + log_pos= (!ev)? group_master_log_pos : + ((thd->options & OPTION_BEGIN || !ev->log_pos) ? + group_master_log_pos : ev->log_pos - ev->data_written); } else { /* until_condition == UNTIL_RELAY_POS */ @@ -3333,9 +3337,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) hits the UNTIL barrier. */ if (rli->until_condition != RELAY_LOG_INFO::UNTIL_NONE && - rli->is_until_satisfied((thd->options & OPTION_BEGIN || !ev->log_pos) ? - rli->group_master_log_pos : - ev->log_pos - ev->data_written)) + rli->is_until_satisfied(thd, ev)) { char buf[22]; sql_print_information("Slave SQL thread stopped because it reached its" @@ -4065,7 +4067,7 @@ Slave SQL thread aborted. Can't execute init_slave query"); */ pthread_mutex_lock(&rli->data_lock); if (rli->until_condition != RELAY_LOG_INFO::UNTIL_NONE && - rli->is_until_satisfied(rli->group_master_log_pos)) + rli->is_until_satisfied(thd, NULL)) { char buf[22]; sql_print_information("Slave SQL thread stopped because it reached its" diff --git a/sql/slave.h b/sql/slave.h index 5ae596f1eb5..78627214eef 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -348,7 +348,7 @@ typedef struct st_relay_log_info void close_temporary_tables(); /* Check if UNTIL condition is satisfied. See slave.cc for more. */ - bool is_until_satisfied(my_off_t master_beg_pos); + bool is_until_satisfied(THD *thd, Log_event *ev); inline ulonglong until_pos() { return ((until_condition == UNTIL_MASTER_POS) ? group_master_log_pos : From 9c23a442b257c0ddb9066930c7bf9b0aac6cacdd Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Fri, 13 Nov 2009 10:30:56 +0000 Subject: [PATCH 004/157] BUG#48738: Backport patch for Bug 34582 to 5.0 codebase. From BUG 34582 commit message: Issuing 'FLUSH LOGS' does not close and reopen indexfile. Instead a SEEK_SET is performed. This patch makes index file to be closed and reopened whenever a rotation happens (FLUSH LOGS is issued or binary log exceeds maximum configured size). --- .../r/binlog_delete_and_flush_index.result | 44 +++++ .../t/binlog_delete_and_flush_index.test | 176 ++++++++++++++++++ sql/log.cc | 10 +- 3 files changed, 226 insertions(+), 4 deletions(-) create mode 100644 mysql-test/r/binlog_delete_and_flush_index.result create mode 100644 mysql-test/t/binlog_delete_and_flush_index.test diff --git a/mysql-test/r/binlog_delete_and_flush_index.result b/mysql-test/r/binlog_delete_and_flush_index.result new file mode 100644 index 00000000000..153900f3081 --- /dev/null +++ b/mysql-test/r/binlog_delete_and_flush_index.result @@ -0,0 +1,44 @@ +RESET MASTER; +CREATE TABLE t1 (a int); +### assertion: index file contains regular entries +SET @index=LOAD_FILE('MYSQLD_DATADIR/master-bin.index'); +master-bin.000001 + +### assertion: show original binlogs +show binary logs; +Log_name File_size +master-bin.000001 # +### assertion: binlog contents from regular entries +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a int) +FLUSH LOGS; +### assertion: index file contains renamed binlog and the new one +SET @index=LOAD_FILE('MYSQLD_DATADIR/master-bin.index'); +master-bin-b34582.000001 +master-bin.000002 + +### assertion: original binlog content still exists, despite we +### renamed and changed the index file +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin-b34582.000001 # Query # # use `test`; CREATE TABLE t1 (a int) +### assertion: user changed binlog index shows correct entries +show binary logs; +Log_name File_size +master-bin-b34582.000001 # +master-bin.000002 # +DROP TABLE t1; +### assertion: purging binlogs up to binlog created after instrumenting index file should work +PURGE BINARY LOGS TO 'master-bin.000002'; +### assertion: show binary logs should only contain latest binlog +show binary logs; +Log_name File_size +master-bin.000002 # +### assertion: assert that binlog files were indeed purged (using file_exists calls) +### assertion: assert that not purged binlog file exists +### assertion: show index file contents and these should match show binary logs issued above +SET @index=LOAD_FILE('MYSQLD_DATADIR/master-bin.index'); +master-bin.000002 + +RESET MASTER; diff --git a/mysql-test/t/binlog_delete_and_flush_index.test b/mysql-test/t/binlog_delete_and_flush_index.test new file mode 100644 index 00000000000..6784043386d --- /dev/null +++ b/mysql-test/t/binlog_delete_and_flush_index.test @@ -0,0 +1,176 @@ +# BUG#34582: FLUSH LOGS does not close and reopen the binlog index +# file +# +# WHAT +# ==== +# +# We want to test that FLUSH LOGS closes and reopens binlog index +# file. +# +# HOW +# === +# +# PREPARE: +# 1. create some binlog events +# 2. show index content, binlog events and binlog contents +# for mysql-bin.000001 +# 3. copy the mysql-bin.000001 to mysql-bin-b34582.000001 +# 4. change the index file so that mysql-bin.000001 is replaced +# with mysql-bin-b34582.000001 +# 5. FLUSH the logs so that new index is closed and reopened +# +# ASSERTIONS: +# 1. index file contents shows mysql-bin-b34582.000001 and +# mysql-bin.000002 +# 1. show binary logs shows current index entries +# 2. binlog contents for mysql-bin-b34582.000001 are displayed +# 3. Purge binlogs up to the latest one succeeds +# 4. SHOW BINARY LOGS presents the latest one only after purging +# 5. Purged binlogs files don't exist in the filesystem +# 6. Not purged binlog file exists in the filesystem +# +# CLEAN UP: +# 1. RESET MASTER +# + +-- source include/have_log_bin.inc + +RESET MASTER; + +-- let $datadir= $MYSQLTEST_VARDIR/log +-- let $index=$datadir/master-bin.index +-- chmod 0666 $index + +# action: issue one command so that binlog gets some event +CREATE TABLE t1 (a int); + +-- echo ### assertion: index file contains regular entries +-- replace_regex /[\\\/].*master/MYSQLD_DATADIR\/master/ +-- eval SET @index=LOAD_FILE('$index') +if (`SELECT convert(@@version_compile_os using latin1) + IN ('Win32','Win64','Windows')`) +{ + -- disable_query_log + -- disable_result_log + -- let $a= `SELECT REPLACE (@index, '$datadir\', '')` + -- enable_result_log + -- enable_query_log + + -- echo $a + +} +if (!`SELECT convert(@@version_compile_os using latin1) + IN ('Win32','Win64','Windows')`) +{ + -- disable_query_log + -- disable_result_log + -- let $a= `SELECT REPLACE (@index, '$datadir/', '')` + -- enable_result_log + -- enable_query_log + + -- echo $a +} + +--echo ### assertion: show original binlogs +-- source include/show_binary_logs.inc + +--echo ### assertion: binlog contents from regular entries +-- source include/show_binlog_events.inc + +# action: copy binlogs to other names and change entries in index file +-- copy_file $datadir/master-bin.000001 $datadir/master-bin-b34582.000001 +-- let newbinfile=$datadir/master-bin-b34582.000001 +let INDEX_FILE=$index; +perl; +$newbinfile= $ENV{'newbinfile'}; +$file= $ENV{'INDEX_FILE'}; +open(FILE, ">$file") || die "Unable to open $file."; +truncate(FILE,0); +print FILE $newbinfile . "\n"; +close ($file); +EOF + +# action: should cause rotation, and creation of new binlogs +FLUSH LOGS; + +# file is not used anymore - remove it (mysql closed on flush logs). +-- remove_file $datadir/master-bin.000001 + +-- echo ### assertion: index file contains renamed binlog and the new one +-- replace_regex /[\\\/].*master/MYSQLD_DATADIR\/master/ +-- eval SET @index=LOAD_FILE('$index') +if (`SELECT convert(@@version_compile_os using latin1) + IN ('Win32','Win64','Windows')`) +{ + -- disable_query_log + -- disable_result_log + -- let $a= `SELECT REPLACE (@index, '$datadir\', '')` + -- enable_result_log + -- enable_query_log + + -- echo $a + +} +if (!`SELECT convert(@@version_compile_os using latin1) + IN ('Win32','Win64','Windows')`) +{ + -- disable_query_log + -- disable_result_log + -- let $a= `SELECT REPLACE (@index, '$datadir/', '')` + -- enable_result_log + -- enable_query_log + + -- echo $a +} + +-- echo ### assertion: original binlog content still exists, despite we +-- echo ### renamed and changed the index file +-- source include/show_binlog_events.inc + +-- echo ### assertion: user changed binlog index shows correct entries +-- source include/show_binary_logs.inc + +DROP TABLE t1; + +-- echo ### assertion: purging binlogs up to binlog created after instrumenting index file should work +-- let $current_binlog= query_get_value(SHOW MASTER STATUS, File, 1) +-- eval PURGE BINARY LOGS TO '$current_binlog' + +-- echo ### assertion: show binary logs should only contain latest binlog +-- source include/show_binary_logs.inc + +-- echo ### assertion: assert that binlog files were indeed purged (using file_exists calls) +-- error 1 +-- file_exists $datadir/master-bin-b34852.000001 + +-- echo ### assertion: assert that not purged binlog file exists +-- file_exists $datadir/$current_binlog + +-- echo ### assertion: show index file contents and these should match show binary logs issued above +-- replace_regex /[\\\/].*master/MYSQLD_DATADIR\/master/ +-- eval SET @index=LOAD_FILE('$index') +if (`SELECT convert(@@version_compile_os using latin1) + IN ('Win32','Win64','Windows')`) +{ + -- disable_query_log + -- disable_result_log + -- let $a= `SELECT REPLACE (@index, '$datadir\', '')` + -- enable_result_log + -- enable_query_log + + -- echo $a + +} +if (!`SELECT convert(@@version_compile_os using latin1) + IN ('Win32','Win64','Windows')`) +{ + -- disable_query_log + -- disable_result_log + -- let $a= `SELECT REPLACE (@index, '$datadir/', '')` + -- enable_result_log + -- enable_query_log + + -- echo $a +} + +RESET MASTER; diff --git a/sql/log.cc b/sql/log.cc index c042651216c..8c0abaeff44 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1635,7 +1635,7 @@ void MYSQL_LOG::new_file(bool need_lock) old_name=name; save_log_type=log_type; name=0; // Don't free name - close(LOG_CLOSE_TO_BE_OPENED); + close(LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX); /* Note that at this point, log_type != LOG_CLOSED (important for is_open()). @@ -1649,9 +1649,11 @@ void MYSQL_LOG::new_file(bool need_lock) Format_description_log_event written at server startup, which should trigger temp tables deletion on slaves. */ - - open(old_name, save_log_type, new_name_ptr, - io_cache_type, no_auto_events, max_size, 1); + + /* reopen index binlog file, BUG#34582 */ + if (!open_index_file(index_file_name, 0)) + open(old_name, save_log_type, new_name_ptr, + io_cache_type, no_auto_events, max_size, 1); my_free(old_name,MYF(0)); end: From 87349334004e7f3ae3beeb347661ffba18df3e38 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Tue, 17 Nov 2009 20:02:16 +0100 Subject: [PATCH 005/157] Bug#48846: Too much time spent in ha_partition::records_in_range if not able to prune Problem was that ha_partition::records_in_range called records_in_range for all non pruned partitions, even if an estimate should be given. Solution is to only use 1/3 of the partitions (up to 10) for records_in_range and estimate the total from this subset. (And continue until a non zero return value from the called partitions records_in_range is given, since 0 means no rows will match.) sql/ha_partition.cc: Bug#48846: Too much time spent in ha_partition::records_in_range if not able to prune estimate_rows_upper_bound and records_in_range are very similar (the only difference is the function and its parameters to use) so I created a common function for this. Since these calls from the optimizer are only estimates, it is not neccesary to call them for every partition, it can use a much smaller subset of the used partitions instead, which improves performance for selects. sql/ha_partition.h: Bug#48846: Too much time spent in ha_partition::records_in_range if not able to prune Added two private functions to help some optimizer calls. --- sql/ha_partition.cc | 144 ++++++++++++++++++++++++++++---------------- sql/ha_partition.h | 12 ++++ 2 files changed, 105 insertions(+), 51 deletions(-) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 451631ff373..b854e270029 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5747,6 +5747,23 @@ const key_map *ha_partition::keys_to_use_for_scanning() DBUG_RETURN(m_file[0]->keys_to_use_for_scanning()); } +#define MAX_PARTS_FOR_OPTIMIZER_CALLS 10 +/* + Prepare start variables for estimating optimizer costs. + + @param[out] num_used_parts Number of partitions after pruning. + @param[out] check_min_num Number of partitions to call. + @param[out] first first used partition. +*/ +void ha_partition::partitions_optimizer_call_preparations(uint *first, + uint *num_used_parts, + uint *check_min_num) +{ + *first= bitmap_get_first_set(&(m_part_info->used_partitions)); + *num_used_parts= bitmap_bits_set(&(m_part_info->used_partitions)); + *check_min_num= min(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts); +} + /* Return time for a scan of the table @@ -5760,43 +5777,67 @@ const key_map *ha_partition::keys_to_use_for_scanning() double ha_partition::scan_time() { - double scan_time= 0; - handler **file; + double scan_time= 0.0; + uint first, part_id, num_used_parts, check_min_num, partitions_called= 0; DBUG_ENTER("ha_partition::scan_time"); - for (file= m_file; *file; file++) - if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file))) - scan_time+= (*file)->scan_time(); + partitions_optimizer_call_preparations(&first, &num_used_parts, &check_min_num); + for (part_id= first; partitions_called < num_used_parts ; part_id++) + { + if (!bitmap_is_set(&(m_part_info->used_partitions), part_id)) + continue; + scan_time+= m_file[part_id]->scan_time(); + partitions_called++; + if (partitions_called >= check_min_num && scan_time != 0.0) + { + DBUG_RETURN(scan_time * + (double) num_used_parts / (double) partitions_called); + } + } DBUG_RETURN(scan_time); } /* - Get time to read + Estimate rows for records_in_range or estimate_rows_upper_bound. - SYNOPSIS - read_time() - index Index number used - ranges Number of ranges - rows Number of rows + @param is_records_in_range call records_in_range instead of + estimate_rows_upper_bound. + @param inx (only for records_in_range) index to use. + @param min_key (only for records_in_range) start of range. + @param max_key (only for records_in_range) end of range. - RETURN VALUE - time for read - - DESCRIPTION - This will be optimised later to include whether or not the index can - be used with partitioning. To achieve we need to add another parameter - that specifies how many of the index fields that are bound in the ranges. - Possibly added as a new call to handlers. + @return Number of rows or HA_POS_ERROR. */ - -double ha_partition::read_time(uint index, uint ranges, ha_rows rows) +ha_rows ha_partition::estimate_rows(bool is_records_in_range, uint inx, + key_range *min_key, key_range *max_key) { - DBUG_ENTER("ha_partition::read_time"); + ha_rows rows, estimated_rows= 0; + uint first, part_id, num_used_parts, check_min_num, partitions_called= 0; + DBUG_ENTER("ha_partition::records_in_range"); - DBUG_RETURN(m_file[0]->read_time(index, ranges, rows)); + partitions_optimizer_call_preparations(&first, &num_used_parts, &check_min_num); + for (part_id= first; partitions_called < num_used_parts ; part_id++) + { + if (!bitmap_is_set(&(m_part_info->used_partitions), part_id)) + continue; + if (is_records_in_range) + rows= m_file[part_id]->records_in_range(inx, min_key, max_key); + else + rows= m_file[part_id]->estimate_rows_upper_bound(); + if (rows == HA_POS_ERROR) + DBUG_RETURN(HA_POS_ERROR); + estimated_rows+= rows; + partitions_called++; + if (partitions_called >= check_min_num && estimated_rows) + { + DBUG_RETURN(estimated_rows * num_used_parts / partitions_called); + } + } + DBUG_RETURN(estimated_rows); } + /* Find number of records in a range @@ -5824,22 +5865,9 @@ double ha_partition::read_time(uint index, uint ranges, ha_rows rows) ha_rows ha_partition::records_in_range(uint inx, key_range *min_key, key_range *max_key) { - handler **file; - ha_rows in_range= 0; DBUG_ENTER("ha_partition::records_in_range"); - file= m_file; - do - { - if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file))) - { - ha_rows tmp_in_range= (*file)->records_in_range(inx, min_key, max_key); - if (tmp_in_range == HA_POS_ERROR) - DBUG_RETURN(tmp_in_range); - in_range+= tmp_in_range; - } - } while (*(++file)); - DBUG_RETURN(in_range); + DBUG_RETURN(estimate_rows(TRUE, inx, min_key, max_key)); } @@ -5855,22 +5883,36 @@ ha_rows ha_partition::records_in_range(uint inx, key_range *min_key, ha_rows ha_partition::estimate_rows_upper_bound() { - ha_rows rows, tot_rows= 0; - handler **file; DBUG_ENTER("ha_partition::estimate_rows_upper_bound"); - file= m_file; - do - { - if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file))) - { - rows= (*file)->estimate_rows_upper_bound(); - if (rows == HA_POS_ERROR) - DBUG_RETURN(HA_POS_ERROR); - tot_rows+= rows; - } - } while (*(++file)); - DBUG_RETURN(tot_rows); + DBUG_RETURN(estimate_rows(FALSE, 0, NULL, NULL)); +} + + +/* + Get time to read + + SYNOPSIS + read_time() + index Index number used + ranges Number of ranges + rows Number of rows + + RETURN VALUE + time for read + + DESCRIPTION + This will be optimised later to include whether or not the index can + be used with partitioning. To achieve we need to add another parameter + that specifies how many of the index fields that are bound in the ranges. + Possibly added as a new call to handlers. +*/ + +double ha_partition::read_time(uint index, uint ranges, ha_rows rows) +{ + DBUG_ENTER("ha_partition::read_time"); + + DBUG_RETURN(m_file[0]->read_time(index, ranges, rows)); } diff --git a/sql/ha_partition.h b/sql/ha_partition.h index c08b1f77eca..9f6d9e0a5ba 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -547,6 +547,18 @@ public: ------------------------------------------------------------------------- */ +private: + /* + Helper function to get the minimum number of partitions to use for + the optimizer hints/cost calls. + */ + void partitions_optimizer_call_preparations(uint *num_used_parts, + uint *check_min_num, + uint *first); + ha_rows estimate_rows(bool is_records_in_range, uint inx, + key_range *min_key, key_range *max_key); +public: + /* keys_to_use_for_scanning can probably be implemented as the intersection of all underlying handlers if mixed handlers are used. From f20d15d07faa14a865148e6d965a908138e36bbf Mon Sep 17 00:00:00 2001 From: Jim Winstead Date: Mon, 23 Nov 2009 13:54:27 -0800 Subject: [PATCH 006/157] Fix C99 aliasing violation due to mismatched types that were papered over with a cast. (Bug #48284) --- libmysql/libmysql.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 77ff2a01d7c..98955c8fc89 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -2285,7 +2285,7 @@ mysql_stmt_param_metadata(MYSQL_STMT *stmt) /* Store type of parameter in network buffer. */ -static void store_param_type(char **pos, MYSQL_BIND *param) +static void store_param_type(unsigned char **pos, MYSQL_BIND *param) { uint typecode= param->buffer_type | (param->is_unsigned ? 32768 : 0); int2store(*pos, typecode); @@ -2565,7 +2565,7 @@ int cli_stmt_execute(MYSQL_STMT *stmt) that is sent to the server. */ for (param= stmt->params; param < param_end ; param++) - store_param_type((char**) &net->write_pos, param); + store_param_type(&net->write_pos, param); } for (param= stmt->params; param < param_end; param++) From dfe177aa227c0bbdb4beb844ab7f62ca4e6106b6 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Tue, 24 Nov 2009 20:04:02 +0000 Subject: [PATCH 007/157] BUG#48340: rpl_cross_version: Found warnings/errors in server log file! Valgrind reports a conditional jump that depends on uninitialized data while doing a LOAD DATA and for this test case only. This test case, tests that loading data from a 4.0 or 4.1 instance into a 5.1 instance is working. As such it handles old binary log with a different set of events than currently 5.1 codebase uses. See the following reference for details: http://forge.mysql.com/wiki/MySQL_Internals_Binary_Log#LOAD_DATA_INFILE_Events Problem: The server is handling an Execute_load_log_event, which results in reading a Load_log_event from the binary log and applying it. When applying the Load_log_event, some variable setup is done and then mysql_load is called. Late in mysql_load execution, if not in row mode logging, the event is binlogged write_execute_load_query_log_event. In write_execute_load_query_log_event, thd->lex->local_file is inspected. The problem is that it has not been set before in the execution stack. This causes valgrind to report the warning. Fix: We fix this by initializing thd->lex->local_file to be the same as the value of Load_log_event::local_fname, when lex_start is called inside Load_log_event::do_apply_event. --- sql/log_event.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/log_event.cc b/sql/log_event.cc index 2cb253c9c56..73580636b7b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -4510,6 +4510,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli, as the present method does not call mysql_parse(). */ lex_start(thd); + thd->lex->local_file= local_fname; mysql_reset_thd_for_next_command(thd); if (!use_rli_only_for_errors) From 7853f553be39b2e3470fd72bf60b4b814dea63f0 Mon Sep 17 00:00:00 2001 From: Evgeny Potemkin Date: Tue, 1 Dec 2009 21:28:45 +0300 Subject: [PATCH 008/157] Bug#48508: Crash on prepared statement re-execution. Actually there is two different bugs. The first one caused crash on queries with WHERE condition over views containing WHERE condition. A wrong check for prepared statement phase led to items for view fields being allocated in the execution memory and freed at the end of execution. Thus the optimized WHERE condition refers to unallocated memory on the second execution and server crashed. The second one caused by the Item_cond::compile function not saving changes it made to the item tree. Thus on the next execution changes weren't reverted and server crashed on dereferencing of unallocated space. The new helper function called is_stmt_prepare_or_first_stmt_execute is added to the Query_arena class. The find_field_in_view function now uses is_stmt_prepare_or_first_stmt_execute() to check whether newly created view items should be freed at the end of the query execution. The Item_cond::compile function now saves changes it makes to item tree. mysql-test/r/ps.result: Added a test case for the bug#48508. mysql-test/t/ps.test: Added a test case for the bug#48508. sql/item_cmpfunc.cc: Bug#48508: Crash on prepared statement re-execution. The Item_cond::compile function now saves changes it makes to item tree. sql/sql_base.cc: Bug#48508: Crash on prepared statement re-execution. The find_field_in_view function now uses is_stmt_prepare_or_first_stmt_execute() to check whether newly created view items should be freed at the end of the query execution. sql/sql_class.h: Bug#48508: Crash on prepared statement re-execution. The Query_arena::is_stmt_prepare_or_first_sp_execute function now correctly do its check. --- mysql-test/r/ps.result | 23 +++++++++++++++++++++++ mysql-test/t/ps.test | 21 +++++++++++++++++++++ sql/item_cmpfunc.cc | 2 +- sql/sql_base.cc | 3 ++- sql/sql_class.h | 2 ++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 43c50998e20..e7894388494 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1891,4 +1891,27 @@ execute stmt using @arg; ? -12345.5432100000 deallocate prepare stmt; +# +# Bug#48508: Crash on prepared statement re-execution. +# +create table t1(b int); +insert into t1 values (0); +create view v1 AS select 1 as a from t1 where b; +prepare stmt from "select * from v1 where a"; +execute stmt; +a +execute stmt; +a +drop table t1; +drop view v1; +create table t1(a bigint); +create table t2(b tinyint); +insert into t2 values (null); +prepare stmt from "select 1 from t1 join t2 on a xor b where b > 1 and a =1"; +execute stmt; +1 +execute stmt; +1 +drop table t1,t2; +# End of 5.0 tests. diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index d9e593fd76f..6134efb5c5c 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1973,4 +1973,25 @@ select @arg; execute stmt using @arg; deallocate prepare stmt; +--echo # +--echo # Bug#48508: Crash on prepared statement re-execution. +--echo # +create table t1(b int); +insert into t1 values (0); +create view v1 AS select 1 as a from t1 where b; +prepare stmt from "select * from v1 where a"; +execute stmt; +execute stmt; +drop table t1; +drop view v1; + +create table t1(a bigint); +create table t2(b tinyint); +insert into t2 values (null); +prepare stmt from "select 1 from t1 join t2 on a xor b where b > 1 and a =1"; +execute stmt; +execute stmt; +drop table t1,t2; +--echo # + --echo End of 5.0 tests. diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 8c655cdc369..d03c68b3560 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -3907,7 +3907,7 @@ Item *Item_cond::compile(Item_analyzer analyzer, byte **arg_p, byte *arg_v= *arg_p; Item *new_item= item->compile(analyzer, &arg_v, transformer, arg_t); if (new_item && new_item != item) - li.replace(new_item); + current_thd->change_item_tree(li.ref(), new_item); } return Item_func::transform(transformer, arg_t); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 178c3e12e23..88d1e8879d1 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3481,7 +3481,8 @@ find_field_in_view(THD *thd, TABLE_LIST *table_list, if (!my_strcasecmp(system_charset_info, field_it.name(), name)) { // in PS use own arena or data will be freed after prepare - if (register_tree_change && thd->stmt_arena->is_stmt_prepare_or_first_sp_execute()) + if (register_tree_change && + thd->stmt_arena->is_stmt_prepare_or_first_stmt_execute()) arena= thd->activate_stmt_arena_if_needed(&backup); /* create_item() may, or may not create a new Item, depending on diff --git a/sql/sql_class.h b/sql/sql_class.h index b41a5d5c6b7..ac058bca4f9 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -759,6 +759,8 @@ public: { return state == INITIALIZED_FOR_SP; } inline bool is_stmt_prepare_or_first_sp_execute() const { return (int)state < (int)PREPARED; } + inline bool is_stmt_prepare_or_first_stmt_execute() const + { return (int)state <= (int)PREPARED; } inline bool is_first_stmt_execute() const { return state == PREPARED; } inline bool is_stmt_execute() const { return state == PREPARED || state == EXECUTED; } From d7abca9ac38fc36eb3ff7f96409c0cabe5f5c03e Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 2 Dec 2009 15:17:08 +0400 Subject: [PATCH 009/157] Bug#48766 SHOW CREATE FUNCTION returns extra data in return clause Problem: SHOW CREATE FUNCTION and SELECT DTD_IDENTIFIER FROM I_S.ROUTINES returned wrong values in case of ENUM return data type and UCS2 character set. Fix: the string to collect returned data type was incorrectly set to "binary" character set, therefore UCS2 values where returned with extra '\0' characters. Setting string character set to creation_ctx->get_client_cs() in sp_find_routine(), and to system_charset_info in sp_create_routine fixes the problem. Adding tests: - the original test with Latin letters - an extra test with non-Latin letters --- mysql-test/r/sp-ucs2.result | 26 ++++++++++++++++++++++++++ mysql-test/t/sp-ucs2.test | 29 +++++++++++++++++++++++++++++ sql/sp.cc | 2 ++ 3 files changed, 57 insertions(+) diff --git a/mysql-test/r/sp-ucs2.result b/mysql-test/r/sp-ucs2.result index ce6be5b0a65..1c266e38d97 100644 --- a/mysql-test/r/sp-ucs2.result +++ b/mysql-test/r/sp-ucs2.result @@ -12,3 +12,29 @@ a foo string drop function bug17615| drop table t3| +SET NAMES utf8; +DROP FUNCTION IF EXISTS bug48766; +CREATE FUNCTION bug48766 () +RETURNS ENUM( 'w' ) CHARACTER SET ucs2 +RETURN 0; +SHOW CREATE FUNCTION bug48766; +Function sql_mode Create Function character_set_client collation_connection Database Collation +bug48766 CREATE DEFINER=`root`@`localhost` FUNCTION `bug48766`() RETURNS enum('w') CHARSET ucs2 +RETURN 0 utf8 utf8_general_ci latin1_swedish_ci +SELECT DTD_IDENTIFIER FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_NAME='bug48766'; +DTD_IDENTIFIER +enum('w') CHARSET ucs2 +DROP FUNCTION bug48766; +CREATE FUNCTION bug48766 () +RETURNS ENUM('а','б','в','г') CHARACTER SET ucs2 +RETURN 0; +SHOW CREATE FUNCTION bug48766; +Function sql_mode Create Function character_set_client collation_connection Database Collation +bug48766 CREATE DEFINER=`root`@`localhost` FUNCTION `bug48766`() RETURNS enum('а','б','в','г') CHARSET ucs2 +RETURN 0 utf8 utf8_general_ci latin1_swedish_ci +SELECT DTD_IDENTIFIER FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_NAME='bug48766'; +DTD_IDENTIFIER +enum('а','б','в','г') CHARSET ucs2 +DROP FUNCTION bug48766; diff --git a/mysql-test/t/sp-ucs2.test b/mysql-test/t/sp-ucs2.test index 7dd88b04871..7d6b62dfea0 100644 --- a/mysql-test/t/sp-ucs2.test +++ b/mysql-test/t/sp-ucs2.test @@ -26,3 +26,32 @@ drop table t3| delimiter ;| + +# +# Bug#48766 SHOW CREATE FUNCTION returns extra data in return clause +# +SET NAMES utf8; +--disable_warnings +DROP FUNCTION IF EXISTS bug48766; +--enable_warnings +# +# Test that Latin letters are not prepended with extra '\0'. +# +CREATE FUNCTION bug48766 () + RETURNS ENUM( 'w' ) CHARACTER SET ucs2 + RETURN 0; +SHOW CREATE FUNCTION bug48766; +SELECT DTD_IDENTIFIER FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_NAME='bug48766'; +DROP FUNCTION bug48766; +# +# Test non-Latin characters +# +CREATE FUNCTION bug48766 () + RETURNS ENUM('а','б','в','г') CHARACTER SET ucs2 + RETURN 0; +SHOW CREATE FUNCTION bug48766; +SELECT DTD_IDENTIFIER FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_NAME='bug48766'; + +DROP FUNCTION bug48766; diff --git a/sql/sp.cc b/sql/sp.cc index d3c5dfb96d0..6fad1d70ffd 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -900,6 +900,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) DBUG_PRINT("enter", ("type: %d name: %.*s",type, (int) sp->m_name.length, sp->m_name.str)); String retstr(64); + retstr.set_charset(system_charset_info); DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE || type == TYPE_ENUM_FUNCTION); @@ -1403,6 +1404,7 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, 64 -- size of "returns" column of mysql.proc. */ String retstr(64); + retstr.set_charset(sp->get_creation_ctx()->get_client_cs()); DBUG_PRINT("info", ("found: 0x%lx", (ulong)sp)); if (sp->m_first_free_instance) From 7622134333ef91e5e88e981288aaf09f7202d54a Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 3 Dec 2009 13:22:34 +0400 Subject: [PATCH 010/157] Bug#44131 Binary-mode "order by" returns records in incorrect order for UTF-8 strings Problem: Item_char_typecast reported wrong max_length when casting to BINARY, which lead, in particular, in wrong "ORDER BY BINARY(char_column)" results. Fix: making Item_char_typecast report correct max_length. @ mysql-test/r/ctype_utf16.result Fixing old incorrect test result. @ mysql-test/r/ctype_utf32.result Fixing old incorrect test result. @ mysql-test/r/ctype_utf8.result Adding new test @ mysql-test/t/ctype_utf8.test Adding new test @ sql/item_timefunc.cc Making Item_char_typecast report correct max_length when cast is done to BINARY. --- mysql-test/r/ctype_utf8.result | 18 ++++++++++++++++++ mysql-test/t/ctype_utf8.test | 10 ++++++++++ sql/item_timefunc.cc | 6 +++--- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 6f4ae965ca0..4c21e66a39c 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1848,6 +1848,24 @@ select hex(_utf8 B'001111111111'); ERROR HY000: Invalid utf8 character string: 'FF' select (_utf8 X'616263FF'); ERROR HY000: Invalid utf8 character string: 'FF' +# +# Bug#44131 Binary-mode "order by" returns records in incorrect order for UTF-8 strings +# +CREATE TABLE t1 (id int not null primary key, name varchar(10)) character set utf8; +INSERT INTO t1 VALUES +(2,'一二三01'),(3,'一二三09'),(4,'一二三02'),(5,'一二三08'), +(6,'一二三11'),(7,'一二三91'),(8,'一二三21'),(9,'一二三81'); +SELECT * FROM t1 ORDER BY BINARY(name); +id name +2 一二三01 +4 一二三02 +5 一二三08 +3 一二三09 +6 一二三11 +8 一二三21 +9 一二三81 +7 一二三91 +DROP TABLE t1; CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL); INSERT INTO t1 VALUES (70000, 1092), (70001, 1085), (70002, 1065); SELECT CONVERT(a, CHAR), CONVERT(b, CHAR) FROM t1 GROUP BY b; diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index f0c769251cf..23c83310886 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1440,6 +1440,16 @@ select hex(_utf8 B'001111111111'); --error ER_INVALID_CHARACTER_STRING select (_utf8 X'616263FF'); +--echo # +--echo # Bug#44131 Binary-mode "order by" returns records in incorrect order for UTF-8 strings +--echo # +CREATE TABLE t1 (id int not null primary key, name varchar(10)) character set utf8; +INSERT INTO t1 VALUES +(2,'一二三01'),(3,'一二三09'),(4,'一二三02'),(5,'一二三08'), +(6,'一二三11'),(7,'一二三91'),(8,'一二三21'),(9,'一二三81'); +SELECT * FROM t1 ORDER BY BINARY(name); +DROP TABLE t1; + # # Bug #36772: When using UTF8, CONVERT with GROUP BY returns truncated results # diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index b293145cc27..ded4d28ca29 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2554,9 +2554,9 @@ void Item_char_typecast::fix_length_and_dec() from_cs != &my_charset_bin && cast_cs != &my_charset_bin); collation.set(cast_cs, DERIVATION_IMPLICIT); - char_length= (cast_length >= 0) ? - cast_length : - args[0]->max_length / args[0]->collation.collation->mbmaxlen; + char_length= (cast_length >= 0) ? cast_length : + args[0]->max_length / + (cast_cs == &my_charset_bin ? 1 : args[0]->collation.collation->mbmaxlen); max_length= char_length * cast_cs->mbmaxlen; } From 9091535c5fc914aecaa51acf6e558ccd9800fd88 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 3 Dec 2009 14:07:46 +0200 Subject: [PATCH 011/157] Bug #48985: show create table crashes if previous access to the table was killed When checking for an error after removing the special view error handler the code was not taking into account that open_tables() may fail because of the current statement being killed. Added a check for thd->killed. Added a client program to test it. --- mysql-test/r/show_check.result | 6 ++++++ mysql-test/t/show_check.test | 22 ++++++++++++++++++++++ sql/sql_show.cc | 2 +- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index e6550bee954..ec0a70ff581 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -1454,4 +1454,10 @@ GRANT PROCESS ON *.* TO test_u@localhost; SHOW ENGINE MYISAM MUTEX; SHOW ENGINE MYISAM STATUS; DROP USER test_u@localhost; +# +# Bug #48985: show create table crashes if previous access to the table +# was killed +# +SHOW CREATE TABLE non_existent; +ERROR 70100: Query execution was interrupted End of 5.1 tests diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 0ce807ae73e..d46261f38d2 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -1207,6 +1207,28 @@ connection default; DROP USER test_u@localhost; +--echo # +--echo # Bug #48985: show create table crashes if previous access to the table +--echo # was killed +--echo # + +connect(con1,localhost,root,,); +CONNECTION con1; +LET $ID= `SELECT connection_id()`; + +CONNECTION default; +--disable_query_log +eval KILL QUERY $ID; +--enable_query_log + +CONNECTION con1; +--error ER_QUERY_INTERRUPTED +SHOW CREATE TABLE non_existent; + +CONNECTION default; +DISCONNECT con1; + + --echo End of 5.1 tests # Wait till all disconnects are completed diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 2c1f360104b..e55000c0f65 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -719,7 +719,7 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list) thd->push_internal_handler(&view_error_suppressor); bool error= open_normal_and_derived_tables(thd, table_list, 0); thd->pop_internal_handler(); - if (error && thd->main_da.is_error()) + if (error && (thd->killed || thd->main_da.is_error())) DBUG_RETURN(TRUE); } From 8fa282cc68b4f7abac8b327935cb449f7c2e7558 Mon Sep 17 00:00:00 2001 From: Evgeny Potemkin Date: Thu, 3 Dec 2009 16:15:20 +0300 Subject: [PATCH 012/157] Bug#48508: Crash on prepared statement re-execution. Test case cleanup. mysql-test/r/ps.result: Test case cleanup for bug#48508. mysql-test/t/ps.test: Test case cleanup for bug#48508. --- mysql-test/r/ps.result | 2 ++ mysql-test/t/ps.test | 2 ++ 2 files changed, 4 insertions(+) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index e7894388494..8a19b9b17e1 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1902,6 +1902,7 @@ execute stmt; a execute stmt; a +deallocate prepare stmt; drop table t1; drop view v1; create table t1(a bigint); @@ -1912,6 +1913,7 @@ execute stmt; 1 execute stmt; 1 +deallocate prepare stmt; drop table t1,t2; # End of 5.0 tests. diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 6134efb5c5c..8f8e943913f 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1982,6 +1982,7 @@ create view v1 AS select 1 as a from t1 where b; prepare stmt from "select * from v1 where a"; execute stmt; execute stmt; +deallocate prepare stmt; drop table t1; drop view v1; @@ -1991,6 +1992,7 @@ insert into t2 values (null); prepare stmt from "select 1 from t1 join t2 on a xor b where b > 1 and a =1"; execute stmt; execute stmt; +deallocate prepare stmt; drop table t1,t2; --echo # From 699a87110d397def13d783bc89c37f9b012f175a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 3 Dec 2009 17:15:47 +0100 Subject: [PATCH 013/157] This is a patch for bug#41569. "mysql_upgrade (ver 5.1) add 3 fields to mysql.proc table but does not set values". mysql_upgrade (ver 5.1) adds 3 fields (character_set_client, collation_connection and db_collation) to the mysql.proc table, but does not set any values. When we run stored procedures, which were created with mysql 5.0, a warning is logged into the error log. The solution to this is for mysql_upgrade to set default best guess values for these fields. A warning is also written during upgrade, to make the user aware that default values are set. client/mysql_upgrade.c: Result lines which start with "WARNING" are passed through to the output. This way we have a way of triggering WARNING-messages during upgrade directly from the .sql-script. mysql-test/r/mysql_upgrade.result: Expected result of the test. mysql-test/t/mysql_upgrade.test: Added a test-case for the bug. scripts/mysql_system_tables_fix.sql: The new fields are populated, and warnings are written. --- client/mysql_upgrade.c | 4 +++ mysql-test/r/mysql_upgrade.result | 42 +++++++++++++++++++++++++++++ mysql-test/t/mysql_upgrade.test | 17 ++++++++++++ scripts/mysql_system_tables_fix.sql | 30 +++++++++++++++++++++ 4 files changed, 93 insertions(+) diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c index 52c3636219d..81dcdaa71f1 100644 --- a/client/mysql_upgrade.c +++ b/client/mysql_upgrade.c @@ -778,6 +778,10 @@ static int run_sql_fix_privilege_tables(void) found_real_errors++; print_line(line); } + else if (strncmp(line, "WARNING", 7) == 0) + { + print_line(line); + } } while ((line= get_line(line)) && *line); } diff --git a/mysql-test/r/mysql_upgrade.result b/mysql-test/r/mysql_upgrade.result index 384442f8c31..72917988594 100644 --- a/mysql-test/r/mysql_upgrade.result +++ b/mysql-test/r/mysql_upgrade.result @@ -127,3 +127,45 @@ mysql.time_zone_transition OK mysql.time_zone_transition_type OK mysql.user OK set GLOBAL sql_mode=default; +# +# Bug #41569 mysql_upgrade (ver 5.1) add 3 fields to mysql.proc table +# but does not set values. +# +CREATE PROCEDURE testproc() BEGIN END; +UPDATE mysql.proc SET character_set_client = NULL WHERE name LIKE 'testproc'; +UPDATE mysql.proc SET collation_connection = NULL WHERE name LIKE 'testproc'; +UPDATE mysql.proc SET db_collation = NULL WHERE name LIKE 'testproc'; +WARNING: NULL values of the 'character_set_client' column ('mysql.proc' table) have been updated with a default value (latin1). Please verify if necessary. +WARNING: NULL values of the 'collation_connection' column ('mysql.proc' table) have been updated with a default value (latin1_swedish_ci). Please verify if necessary. +WARNING: NULL values of the 'db_collation' column ('mysql.proc' table) have been updated with default values. Please verify if necessary. +mtr.global_suppressions OK +mtr.test_suppressions OK +mysql.columns_priv OK +mysql.db OK +mysql.event OK +mysql.func OK +mysql.general_log +Error : You can't use locks with log tables. +status : OK +mysql.help_category OK +mysql.help_keyword OK +mysql.help_relation OK +mysql.help_topic OK +mysql.host OK +mysql.ndb_binlog_index OK +mysql.plugin OK +mysql.proc OK +mysql.procs_priv OK +mysql.servers OK +mysql.slow_log +Error : You can't use locks with log tables. +status : OK +mysql.tables_priv OK +mysql.time_zone OK +mysql.time_zone_leap_second OK +mysql.time_zone_name OK +mysql.time_zone_transition OK +mysql.time_zone_transition_type OK +mysql.user OK +CALL testproc(); +DROP PROCEDURE testproc; diff --git a/mysql-test/t/mysql_upgrade.test b/mysql-test/t/mysql_upgrade.test index d1f97d7287e..937c9d7a212 100644 --- a/mysql-test/t/mysql_upgrade.test +++ b/mysql-test/t/mysql_upgrade.test @@ -89,3 +89,20 @@ DROP USER mysqltest1@'%'; set GLOBAL sql_mode='STRICT_ALL_TABLES,ANSI_QUOTES,NO_ZERO_DATE'; --exec $MYSQL_UPGRADE --skip-verbose --force 2>&1 eval set GLOBAL sql_mode=default; + + +--echo # +--echo # Bug #41569 mysql_upgrade (ver 5.1) add 3 fields to mysql.proc table +--echo # but does not set values. +--echo # + +# Create a stored procedure and set the fields in question to null. +# When running mysql_upgrade, a warning should be written. + +CREATE PROCEDURE testproc() BEGIN END; +UPDATE mysql.proc SET character_set_client = NULL WHERE name LIKE 'testproc'; +UPDATE mysql.proc SET collation_connection = NULL WHERE name LIKE 'testproc'; +UPDATE mysql.proc SET db_collation = NULL WHERE name LIKE 'testproc'; +--exec $MYSQL_UPGRADE --skip-verbose --force 2>&1 +CALL testproc(); +DROP PROCEDURE testproc; diff --git a/scripts/mysql_system_tables_fix.sql b/scripts/mysql_system_tables_fix.sql index 1844860c84d..4260aee9142 100644 --- a/scripts/mysql_system_tables_fix.sql +++ b/scripts/mysql_system_tables_fix.sql @@ -415,18 +415,48 @@ ALTER TABLE proc ADD character_set_client ALTER TABLE proc MODIFY character_set_client char(32) collate utf8_bin DEFAULT NULL; +SELECT CASE WHEN COUNT(*) > 0 THEN +CONCAT ("WARNING: NULL values of the 'character_set_client' column ('mysql.proc' table) have been updated with a default value (", @@character_set_client, "). Please verify if necessary.") +ELSE NULL +END +AS value FROM proc WHERE character_set_client IS NULL; + +UPDATE proc SET character_set_client = @@character_set_client + WHERE character_set_client IS NULL; + ALTER TABLE proc ADD collation_connection char(32) collate utf8_bin DEFAULT NULL AFTER character_set_client; ALTER TABLE proc MODIFY collation_connection char(32) collate utf8_bin DEFAULT NULL; +SELECT CASE WHEN COUNT(*) > 0 THEN +CONCAT ("WARNING: NULL values of the 'collation_connection' column ('mysql.proc' table) have been updated with a default value (", @@collation_connection, "). Please verify if necessary.") +ELSE NULL +END +AS value FROM proc WHERE collation_connection IS NULL; + +UPDATE proc SET collation_connection = @@collation_connection + WHERE collation_connection IS NULL; + ALTER TABLE proc ADD db_collation char(32) collate utf8_bin DEFAULT NULL AFTER collation_connection; ALTER TABLE proc MODIFY db_collation char(32) collate utf8_bin DEFAULT NULL; +SELECT CASE WHEN COUNT(*) > 0 THEN +CONCAT ("WARNING: NULL values of the 'db_collation' column ('mysql.proc' table) have been updated with default values. Please verify if necessary.") +ELSE NULL +END +AS value FROM proc WHERE db_collation IS NULL; + +UPDATE proc AS p SET db_collation = + ( SELECT DEFAULT_COLLATION_NAME + FROM INFORMATION_SCHEMA.SCHEMATA + WHERE SCHEMA_NAME = p.db) + WHERE db_collation IS NULL; + ALTER TABLE proc ADD body_utf8 longblob DEFAULT NULL AFTER db_collation; ALTER TABLE proc MODIFY body_utf8 longblob DEFAULT NULL; From 43d8e02f596f3e87ff45710566aa39cfaf863852 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Thu, 3 Dec 2009 23:38:09 +0400 Subject: [PATCH 014/157] Bug #38883: thd_security_context is not thread safe, crashes? After-push minor code cleanup for WL 2360: unnecessary external reference to LOCK_thread_count has been removed from ha_innodb.cc. --- storage/innobase/handler/ha_innodb.cc | 6 ------ storage/innodb_plugin/handler/ha_innodb.cc | 3 --- 2 files changed, 9 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 30b4fc13012..2467e7b19b5 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -40,12 +40,6 @@ have disabled the InnoDB inlining in this file. */ #include "ha_innodb.h" #include -#ifndef MYSQL_SERVER -/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t -is defined the same in both builds: the MySQL server and the InnoDB plugin. */ -extern pthread_mutex_t LOCK_thread_count; -#endif /* MYSQL_SERVER */ - /** to protect innobase_open_files */ static pthread_mutex_t innobase_share_mutex; /** to force correct commit order in binlog */ diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index b51e9186fe4..47b8203091c 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -110,9 +110,6 @@ extern "C" { # ifndef MYSQL_PLUGIN_IMPORT # define MYSQL_PLUGIN_IMPORT /* nothing */ # endif /* MYSQL_PLUGIN_IMPORT */ -/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t -is defined the same in both builds: the MySQL server and the InnoDB plugin. */ -extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count; #if MYSQL_VERSION_ID < 50124 /* this is defined in mysql_priv.h inside #ifdef MYSQL_SERVER From a4c50983f4bb06209969421dc044bfbc2932f025 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Fri, 4 Dec 2009 14:40:42 +0000 Subject: [PATCH 015/157] BUG#45292 orphan binary log created when starting server twice This patch fixes three bugs as follows. First, aborting the server while purging binary logs might generate orphan files due to how the purge operation was implemented: (purge routine - sql/log.cc - MYSQL_BIN_LOG::purge_logs) 1 - register the files to be removed in a temporary buffer. 2 - update the log-bin.index. 3 - flush the log-bin.index. 4 - erase the files whose names where register in the temporary buffer in step 1. Thus a failure while executing step 4 would generate an orphan file. Second, a similar issue might happen while creating a new binary as follows: (create routine - sql/log.cc - MYSQL_BIN_LOG::open) 1 - open the new log-bin. 2 - update the log-bin.index. Thus a failure while executing step 1 would generate an orphan file. To fix these issues, we record the files to be purged or created before really removing or adding them. So if a failure happens such records can be used to automatically remove dangling files. The new steps might be outlined as follows: (purge routine - sql/log.cc - MYSQL_BIN_LOG::purge_logs) 1 - register the files to be removed in the log-bin.~rec~ placed in the data directory. 2 - update the log-bin.index. 3 - flush the log-bin.index. 4 - delete the log-bin.~rec~. (create routine - sql/log.cc - MYSQL_BIN_LOG::open) 1 - register the file to be created in the log-bin.~rec~ placed in the data directory. 2 - open the new log-bin. 3 - update the log-bin.index. 4 - delete the log-bin.~rec~. (recovery routine - sql/log.cc - MYSQL_BIN_LOG::open_index_file) 1 - open the log-bin.index. 2 - open the log-bin.~rec~. 3 - for each file in log-bin.~rec~. 3.1 Check if the file is in the log-bin.index and if so ignore it. 3.2 Otherwise, delete it. The third issue can be described as follows. The purge operation was allowing to remove a file in use thus leading to the loss of data and possible inconsistencies between the master and slave. Roughly, the routine was only taking into account the dump threads and so if a slave was not connect the file might be delete even though it was in use. --- mysql-test/suite/binlog/r/binlog_index.result | 113 ++++- mysql-test/suite/binlog/t/binlog_index.test | 165 ++++++- sql/log.cc | 440 +++++++++++++----- sql/log.h | 26 +- sql/mysqld.cc | 4 +- sql/rpl_rli.cc | 4 +- 6 files changed, 628 insertions(+), 124 deletions(-) diff --git a/mysql-test/suite/binlog/r/binlog_index.result b/mysql-test/suite/binlog/r/binlog_index.result index d49ceb00501..06d8baf23bf 100644 --- a/mysql-test/suite/binlog/r/binlog_index.result +++ b/mysql-test/suite/binlog/r/binlog_index.result @@ -1,3 +1,8 @@ +call mtr.add_suppression('Attempting backtrace'); +call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to process registered files that would be purged.'); +call mtr.add_suppression('MSYQL_BIN_LOG::open failed to sync the index file'); +call mtr.add_suppression('Turning logging off for the whole duration of the MySQL server process.'); +call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to clean registers before purging logs.'); flush logs; flush logs; flush logs; @@ -21,7 +26,6 @@ flush logs; *** must be a warning master-bin.000001 was not found *** Warnings: Warning 1612 Being purged log master-bin.000001 was not found -Warning 1612 Being purged log master-bin.000001 was not found *** must show one record, of the active binlog, left in the index file after PURGE *** show binary logs; Log_name File_size @@ -37,4 +41,111 @@ Level Code Message Error 1377 a problem with deleting master-bin.000001; consider examining correspondence of your binlog index file to the actual binlog files Error 1377 Fatal error during log purge reset master; +# crash_purge_before_update_index +flush logs; +SET SESSION debug="+d,crash_purge_before_update_index"; +purge binary logs TO 'master-bin.000002'; +ERROR HY000: Lost connection to MySQL server during query +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000001 +master-bin.000002 +master-bin.000003 + +# crash_purge_non_critical_after_update_index +flush logs; +SET SESSION debug="+d,crash_purge_non_critical_after_update_index"; +purge binary logs TO 'master-bin.000004'; +ERROR HY000: Lost connection to MySQL server during query +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000004 +master-bin.000005 + +# crash_purge_critical_after_update_index +flush logs; +SET SESSION debug="+d,crash_purge_critical_after_update_index"; +purge binary logs TO 'master-bin.000006'; +ERROR HY000: Lost connection to MySQL server during query +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000006 +master-bin.000007 + +# crash_create_non_critical_before_update_index +SET SESSION debug="+d,crash_create_non_critical_before_update_index"; +flush logs; +ERROR HY000: Lost connection to MySQL server during query +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000006 +master-bin.000007 +master-bin.000008 + +# crash_create_critical_before_update_index +SET SESSION debug="+d,crash_create_critical_before_update_index"; +flush logs; +ERROR HY000: Lost connection to MySQL server during query +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000006 +master-bin.000007 +master-bin.000008 +master-bin.000009 + +# crash_create_after_update_index +SET SESSION debug="+d,crash_create_after_update_index"; +flush logs; +ERROR HY000: Lost connection to MySQL server during query +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000006 +master-bin.000007 +master-bin.000008 +master-bin.000009 +master-bin.000010 +master-bin.000011 + +# +# This should put the server in unsafe state and stop +# accepting any command. If we inject a fault at this +# point and continue the execution the server crashes. +# Besides the flush command does not report an error. +# +# fault_injection_registering_index +SET SESSION debug="+d,fault_injection_registering_index"; +flush logs; +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000006 +master-bin.000007 +master-bin.000008 +master-bin.000009 +master-bin.000010 +master-bin.000011 +master-bin.000012 + +# fault_injection_updating_index +SET SESSION debug="+d,fault_injection_updating_index"; +flush logs; +SET @index=LOAD_FILE('MYSQLTEST_VARDIR/mysqld.1/data//master-bin.index'); +SELECT @index; +@index +master-bin.000006 +master-bin.000007 +master-bin.000008 +master-bin.000009 +master-bin.000010 +master-bin.000011 +master-bin.000012 +master-bin.000013 + +SET SESSION debug=""; End of tests diff --git a/mysql-test/suite/binlog/t/binlog_index.test b/mysql-test/suite/binlog/t/binlog_index.test index 13287465b88..8e54c028dbd 100644 --- a/mysql-test/suite/binlog/t/binlog_index.test +++ b/mysql-test/suite/binlog/t/binlog_index.test @@ -3,6 +3,15 @@ # source include/have_log_bin.inc; source include/not_embedded.inc; +call mtr.add_suppression('Attempting backtrace'); +call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to process registered files that would be purged.'); +call mtr.add_suppression('MSYQL_BIN_LOG::open failed to sync the index file'); +call mtr.add_suppression('Turning logging off for the whole duration of the MySQL server process.'); +call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to clean registers before purging logs.'); +let $old=`select @@debug`; + +let $MYSQLD_DATADIR= `select @@datadir`; +let $INDEX=$MYSQLD_DATADIR/master-bin.index; # # testing purge binary logs TO @@ -13,7 +22,6 @@ flush logs; flush logs; source include/show_binary_logs.inc; -let $MYSQLD_DATADIR= `select @@datadir`; remove_file $MYSQLD_DATADIR/master-bin.000001; # there must be a warning with file names @@ -66,4 +74,159 @@ rmdir $MYSQLD_DATADIR/master-bin.000001; --disable_warnings reset master; --enable_warnings + +--echo # crash_purge_before_update_index +flush logs; + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug="+d,crash_purge_before_update_index"; +--error 2013 +purge binary logs TO 'master-bin.000002'; + +--enable_reconnect +--source include/wait_until_connected_again.inc + +file_exists $MYSQLD_DATADIR/master-bin.000001; +file_exists $MYSQLD_DATADIR/master-bin.000002; +file_exists $MYSQLD_DATADIR/master-bin.000003; +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +--echo # crash_purge_non_critical_after_update_index +flush logs; + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug="+d,crash_purge_non_critical_after_update_index"; +--error 2013 +purge binary logs TO 'master-bin.000004'; + +--enable_reconnect +--source include/wait_until_connected_again.inc + +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000001; +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000002; +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000003; +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +--echo # crash_purge_critical_after_update_index +flush logs; + +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug="+d,crash_purge_critical_after_update_index"; +--error 2013 +purge binary logs TO 'master-bin.000006'; + +--enable_reconnect +--source include/wait_until_connected_again.inc + +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000004; +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000005; +file_exists $MYSQLD_DATADIR/master-bin.000006; +file_exists $MYSQLD_DATADIR/master-bin.000007; +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000008; +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +--echo # crash_create_non_critical_before_update_index +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug="+d,crash_create_non_critical_before_update_index"; +--error 2013 +flush logs; + +--enable_reconnect +--source include/wait_until_connected_again.inc + +file_exists $MYSQLD_DATADIR/master-bin.000008; +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000009; +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +--echo # crash_create_critical_before_update_index +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug="+d,crash_create_critical_before_update_index"; +--error 2013 +flush logs; + +--enable_reconnect +--source include/wait_until_connected_again.inc + +file_exists $MYSQLD_DATADIR/master-bin.000009; +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000010; +--error 1 +file_exists $MYSQLD_DATADIR/master-bin.000011; +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +--echo # crash_create_after_update_index +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +SET SESSION debug="+d,crash_create_after_update_index"; +--error 2013 +flush logs; + +--enable_reconnect +--source include/wait_until_connected_again.inc + +file_exists $MYSQLD_DATADIR/master-bin.000010; +file_exists $MYSQLD_DATADIR/master-bin.000011; +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +--echo # +--echo # This should put the server in unsafe state and stop +--echo # accepting any command. If we inject a fault at this +--echo # point and continue the execution the server crashes. +--echo # Besides the flush command does not report an error. +--echo # + +--echo # fault_injection_registering_index +SET SESSION debug="+d,fault_injection_registering_index"; +flush logs; +--source include/restart_mysqld.inc + +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +--echo # fault_injection_updating_index +SET SESSION debug="+d,fault_injection_updating_index"; +flush logs; +--source include/restart_mysqld.inc + +--chmod 0644 $INDEX +-- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +-- eval SET @index=LOAD_FILE('$index') +-- replace_regex /\.[\\\/]master/master/ +SELECT @index; + +eval SET SESSION debug="$old"; + --echo End of tests diff --git a/sql/log.cc b/sql/log.cc index b4c9e5eb4cc..f795cdab2ca 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1897,6 +1897,22 @@ void MYSQL_LOG::init(enum_log_type log_type_arg, } +bool MYSQL_LOG::init_and_set_log_file_name(const char *log_name, + const char *new_name, + enum_log_type log_type_arg, + enum cache_type io_cache_type_arg) +{ + init(log_type_arg, io_cache_type_arg); + + if (new_name && !strmov(log_file_name, new_name)) + return TRUE; + else if (!new_name && generate_new_name(log_file_name, log_name)) + return TRUE; + + return FALSE; +} + + /* Open a (new) log file. @@ -1929,17 +1945,14 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, write_error= 0; - init(log_type_arg, io_cache_type_arg); - if (!(name= my_strdup(log_name, MYF(MY_WME)))) { name= (char *)log_name; // for the error message goto err; } - if (new_name) - strmov(log_file_name, new_name); - else if (generate_new_name(log_file_name, name)) + if (init_and_set_log_file_name(name, new_name, + log_type_arg, io_cache_type_arg)) goto err; if (io_cache_type == SEQ_READ_APPEND) @@ -2429,7 +2442,7 @@ MYSQL_BIN_LOG::MYSQL_BIN_LOG() */ index_file_name[0] = 0; bzero((char*) &index_file, sizeof(index_file)); - bzero((char*) &purge_temp, sizeof(purge_temp)); + bzero((char*) &purge_index_file, sizeof(purge_index_file)); } /* this is called only once */ @@ -2473,7 +2486,7 @@ void MYSQL_BIN_LOG::init_pthread_objects() bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg, - const char *log_name) + const char *log_name, bool need_mutex) { File index_file_nr= -1; DBUG_ASSERT(!my_b_inited(&index_file)); @@ -2498,7 +2511,8 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg, init_io_cache(&index_file, index_file_nr, IO_SIZE, WRITE_CACHE, my_seek(index_file_nr,0L,MY_SEEK_END,MYF(0)), - 0, MYF(MY_WME | MY_WAIT_IF_FULL))) + 0, MYF(MY_WME | MY_WAIT_IF_FULL)) || + DBUG_EVALUATE_IF("fault_injection_openning_index", 1, 0)) { /* TODO: all operations creating/deleting the index file or a log, should @@ -2509,6 +2523,28 @@ bool MYSQL_BIN_LOG::open_index_file(const char *index_file_name_arg, my_close(index_file_nr,MYF(0)); return TRUE; } + +#ifdef HAVE_REPLICATION + /* + Sync the index by purging any binary log file that is not registered. + In other words, either purge binary log files that were removed from + the index but not purged from the file system due to a crash or purge + any binary log file that was created but not register in the index + due to a crash. + */ + + if (set_purge_index_file_name(index_file_name_arg) || + open_purge_index_file(FALSE) || + purge_index_entry(NULL, NULL, need_mutex) || + close_purge_index_file() || + DBUG_EVALUATE_IF("fault_injection_recovering_index", 1, 0)) + { + sql_print_error("MYSQL_BIN_LOG::open_index_file failed to sync the index " + "file."); + return TRUE; + } +#endif + return FALSE; } @@ -2533,17 +2569,44 @@ bool MYSQL_BIN_LOG::open(const char *log_name, enum cache_type io_cache_type_arg, bool no_auto_events_arg, ulong max_size_arg, - bool null_created_arg) + bool null_created_arg, + bool need_mutex) { File file= -1; + DBUG_ENTER("MYSQL_BIN_LOG::open"); DBUG_PRINT("enter",("log_type: %d",(int) log_type_arg)); - write_error=0; + if (init_and_set_log_file_name(log_name, new_name, log_type_arg, + io_cache_type_arg)) + { + sql_print_error("MSYQL_BIN_LOG::open failed to generate new file name."); + DBUG_RETURN(1); + } + +#ifdef HAVE_REPLICATION + if (open_purge_index_file(TRUE) || + register_create_index_entry(log_file_name) || + sync_purge_index_file() || + DBUG_EVALUATE_IF("fault_injection_registering_index", 1, 0)) + { + sql_print_error("MSYQL_BIN_LOG::open failed to sync the index file."); + DBUG_RETURN(1); + } + DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", abort();); +#endif + + write_error= 0; /* open the main log file */ - if (MYSQL_LOG::open(log_name, log_type_arg, new_name, io_cache_type_arg)) + if (MYSQL_LOG::open(log_name, log_type_arg, new_name, + io_cache_type_arg)) + { +#ifdef HAVE_REPLICATION + close_purge_index_file(); +#endif DBUG_RETURN(1); /* all warnings issued */ + } init(no_auto_events_arg, max_size_arg); @@ -2569,9 +2632,6 @@ bool MYSQL_BIN_LOG::open(const char *log_name, write_file_name_to_index_file= 1; } - DBUG_ASSERT(my_b_inited(&index_file) != 0); - reinit_io_cache(&index_file, WRITE_CACHE, - my_b_filelength(&index_file), 0, 0); if (need_start_event && !no_auto_events) { /* @@ -2629,23 +2689,44 @@ bool MYSQL_BIN_LOG::open(const char *log_name, if (write_file_name_to_index_file) { +#ifdef HAVE_REPLICATION + DBUG_EXECUTE_IF("crash_create_critical_before_update_index", abort();); +#endif + + DBUG_ASSERT(my_b_inited(&index_file) != 0); + reinit_io_cache(&index_file, WRITE_CACHE, + my_b_filelength(&index_file), 0, 0); /* As this is a new log file, we write the file name to the index file. As every time we write to the index file, we sync it. */ - if (my_b_write(&index_file, (uchar*) log_file_name, - strlen(log_file_name)) || - my_b_write(&index_file, (uchar*) "\n", 1) || - flush_io_cache(&index_file) || + if (DBUG_EVALUATE_IF("fault_injection_updating_index", 1, 0) || + my_b_write(&index_file, (uchar*) log_file_name, + strlen(log_file_name)) || + my_b_write(&index_file, (uchar*) "\n", 1) || + flush_io_cache(&index_file) || my_sync(index_file.file, MYF(MY_WME))) - goto err; + goto err; + +#ifdef HAVE_REPLICATION + DBUG_EXECUTE_IF("crash_create_after_update_index", abort();); +#endif } } log_state= LOG_OPENED; +#ifdef HAVE_REPLICATION + close_purge_index_file(); +#endif + DBUG_RETURN(0); err: +#ifdef HAVE_REPLICATION + if (is_inited_purge_index_file()) + purge_index_entry(NULL, NULL, need_mutex); + close_purge_index_file(); +#endif sql_print_error("Could not use %s for logging (error %d). \ Turning logging off for the whole duration of the MySQL server process. \ To turn it on again: fix the cause, \ @@ -2902,8 +2983,15 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) name=0; // Protect against free close(LOG_CLOSE_TO_BE_OPENED); - /* First delete all old log files */ + /* + First delete all old log files and then update the index file. + As we first delete the log files and do not use sort of logging, + a crash may lead to an inconsistent state where the index has + references to non-existent files. + We need to invert the steps and use the purge_index_file methods + in order to make the operation safe. + */ if (find_log_pos(&linfo, NullS, 0)) { error=1; @@ -2970,8 +3058,8 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) } if (!thd->slave_thread) need_start_event=1; - if (!open_index_file(index_file_name, 0)) - open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0); + if (!open_index_file(index_file_name, 0, FALSE)) + open(save_name, log_type, 0, io_cache_type, no_auto_events, max_size, 0, FALSE); my_free((uchar*) save_name, MYF(0)); err: @@ -3158,7 +3246,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log, bool need_update_threads, ulonglong *decrease_log_space) { - int error; + int error= 0; bool exit_loop= 0; LOG_INFO log_info; THD *thd= current_thd; @@ -3169,33 +3257,15 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log, pthread_mutex_lock(&LOCK_index); if ((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/))) { - sql_print_error("MYSQL_LOG::purge_logs was called with file %s not " + sql_print_error("MYSQL_BIN_LOG::purge_logs was called with file %s not " "listed in the index.", to_log); goto err; } - /* - For crash recovery reasons the index needs to be updated before - any files are deleted. Move files to be deleted into a temp file - to be processed after the index is updated. - */ - if (!my_b_inited(&purge_temp)) + if ((error= open_purge_index_file(TRUE))) { - if ((error=open_cached_file(&purge_temp, mysql_tmpdir, TEMP_PREFIX, - DISK_BUFFER_SIZE, MYF(MY_WME)))) - { - sql_print_error("MYSQL_LOG::purge_logs failed to open purge_temp"); - goto err; - } - } - else - { - if ((error=reinit_io_cache(&purge_temp, WRITE_CACHE, 0, 0, 1))) - { - sql_print_error("MYSQL_LOG::purge_logs failed to reinit purge_temp " - "for write"); - goto err; - } + sql_print_error("MYSQL_BIN_LOG::purge_logs failed to sync the index file."); + goto err; } /* @@ -3205,51 +3275,177 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log, if ((error=find_log_pos(&log_info, NullS, 0 /*no mutex*/))) goto err; while ((strcmp(to_log,log_info.log_file_name) || (exit_loop=included)) && + !is_active(log_info.log_file_name) && !log_in_use(log_info.log_file_name)) { - if ((error=my_b_write(&purge_temp, (const uchar*)log_info.log_file_name, - strlen(log_info.log_file_name))) || - (error=my_b_write(&purge_temp, (const uchar*)"\n", 1))) + if ((error= register_purge_index_entry(log_info.log_file_name))) { - sql_print_error("MYSQL_LOG::purge_logs failed to copy %s to purge_temp", + sql_print_error("MYSQL_BIN_LOG::purge_logs failed to copy %s to register file.", log_info.log_file_name); goto err; } if (find_next_log(&log_info, 0) || exit_loop) break; - } + } + + DBUG_EXECUTE_IF("crash_purge_before_update_index", abort();); + + if ((error= sync_purge_index_file())) + { + sql_print_error("MSYQL_BIN_LOG::purge_logs failed to flush register file."); + goto err; + } /* We know how many files to delete. Update index file. */ if ((error=update_log_index(&log_info, need_update_threads))) { - sql_print_error("MSYQL_LOG::purge_logs failed to update the index file"); + sql_print_error("MSYQL_BIN_LOG::purge_logs failed to update the index file"); goto err; } - DBUG_EXECUTE_IF("crash_after_update_index", abort();); + DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", abort();); - /* Switch purge_temp for read. */ - if ((error=reinit_io_cache(&purge_temp, READ_CACHE, 0, 0, 0))) +err: + /* Read each entry from purge_index_file and delete the file. */ + if (is_inited_purge_index_file() && + (error= purge_index_entry(thd, decrease_log_space, FALSE))) + sql_print_error("MSYQL_BIN_LOG::purge_logs failed to process registered files" + " that would be purged."); + close_purge_index_file(); + + DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", abort();); + + if (need_mutex) + pthread_mutex_unlock(&LOCK_index); + DBUG_RETURN(error); +} + +int MYSQL_BIN_LOG::set_purge_index_file_name(const char *base_file_name) +{ + int error= 0; + DBUG_ENTER("MYSQL_BIN_LOG::set_purge_index_file_name"); + if (fn_format(purge_index_file_name, base_file_name, mysql_data_home, + ".~rec~", MYF(MY_UNPACK_FILENAME | MY_SAFE_PATH | + MY_REPLACE_EXT)) == NULL) { - sql_print_error("MSYQL_LOG::purge_logs failed to reinit purge_temp " + error= 1; + sql_print_error("MYSQL_BIN_LOG::set_purge_index_file_name failed to set " + "file name."); + } + DBUG_RETURN(error); +} + +int MYSQL_BIN_LOG::open_purge_index_file(bool destroy) +{ + int error= 0; + File file= -1; + + DBUG_ENTER("MYSQL_BIN_LOG::open_purge_index_file"); + + if (destroy) + close_purge_index_file(); + + if (!my_b_inited(&purge_index_file)) + { + if ((file= my_open(purge_index_file_name, O_RDWR | O_CREAT | O_BINARY, + MYF(MY_WME | ME_WAITTANG))) < 0 || + init_io_cache(&purge_index_file, file, IO_SIZE, + (destroy ? WRITE_CACHE : READ_CACHE), + 0, 0, MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL))) + { + error= 1; + sql_print_error("MYSQL_BIN_LOG::open_purge_index_file failed to open register " + " file."); + } + } + DBUG_RETURN(error); +} + +int MYSQL_BIN_LOG::close_purge_index_file() +{ + int error= 0; + + DBUG_ENTER("MYSQL_BIN_LOG::close_purge_index_file"); + + if (my_b_inited(&purge_index_file)) + { + end_io_cache(&purge_index_file); + error= my_close(purge_index_file.file, MYF(0)); + } + my_delete(purge_index_file_name, MYF(0)); + bzero((char*) &purge_index_file, sizeof(purge_index_file)); + + DBUG_RETURN(error); +} + +bool MYSQL_BIN_LOG::is_inited_purge_index_file() +{ + DBUG_ENTER("MYSQL_BIN_LOG::is_inited_purge_index_file"); + DBUG_RETURN (my_b_inited(&purge_index_file)); +} + +int MYSQL_BIN_LOG::sync_purge_index_file() +{ + int error= 0; + DBUG_ENTER("MYSQL_BIN_LOG::sync_purge_index_file"); + + if ((error= flush_io_cache(&purge_index_file)) || + (error= my_sync(purge_index_file.file, MYF(MY_WME)))) + DBUG_RETURN(error); + + DBUG_RETURN(error); +} + +int MYSQL_BIN_LOG::register_purge_index_entry(const char *entry) +{ + int error= 0; + DBUG_ENTER("MYSQL_BIN_LOG::register_purge_index_entry"); + + if ((error=my_b_write(&purge_index_file, (const uchar*)entry, strlen(entry))) || + (error=my_b_write(&purge_index_file, (const uchar*)"\n", 1))) + DBUG_RETURN (error); + + DBUG_RETURN(error); +} + +int MYSQL_BIN_LOG::register_create_index_entry(const char *entry) +{ + DBUG_ENTER("MYSQL_BIN_LOG::register_create_index_entry"); + DBUG_RETURN(register_purge_index_entry(entry)); +} + +int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space, + bool need_mutex) +{ + MY_STAT s; + int error= 0; + LOG_INFO log_info; + LOG_INFO check_log_info; + + DBUG_ENTER("MYSQL_BIN_LOG:purge_index_entry"); + + DBUG_ASSERT(my_b_inited(&purge_index_file)); + + if ((error=reinit_io_cache(&purge_index_file, READ_CACHE, 0, 0, 0))) + { + sql_print_error("MSYQL_BIN_LOG::purge_index_entry failed to reinit register file " "for read"); goto err; } - /* Read each entry from purge_temp and delete the file. */ for (;;) { uint length; - if ((length=my_b_gets(&purge_temp, log_info.log_file_name, + if ((length=my_b_gets(&purge_index_file, log_info.log_file_name, FN_REFLEN)) <= 1) { - if (purge_temp.error) + if (purge_index_file.error) { - error= purge_temp.error; - sql_print_error("MSYQL_LOG::purge_logs error %d reading from " - "purge_temp", error); + error= purge_index_file.error; + sql_print_error("MSYQL_BIN_LOG::purge_index_entry error %d reading from " + "register file.", error); goto err; } @@ -3260,9 +3456,6 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log, /* Get rid of the trailing '\n' */ log_info.log_file_name[length-1]= 0; - ha_binlog_index_purge_file(current_thd, log_info.log_file_name); - - MY_STAT s; if (!my_stat(log_info.log_file_name, &s, MYF(0))) { if (my_errno == ENOENT) @@ -3310,64 +3503,92 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log, } else { - DBUG_PRINT("info",("purging %s",log_info.log_file_name)); - if (!my_delete(log_info.log_file_name, MYF(0))) + if ((error= find_log_pos(&check_log_info, log_info.log_file_name, need_mutex))) { - if (decrease_log_space) - *decrease_log_space-= s.st_size; - } - else - { - if (my_errno == ENOENT) - { - if (thd) - { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE), - log_info.log_file_name); - } - sql_print_information("Failed to delete file '%s'", - log_info.log_file_name); - my_errno= 0; - } - else + if (error != LOG_INFO_EOF) { if (thd) { push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, ER_BINLOG_PURGE_FATAL_ERR, - "a problem with deleting %s; " - "consider examining correspondence " - "of your binlog index file " - "to the actual binlog files", + "a problem with deleting %s and " + "reading the binlog index file", log_info.log_file_name); } else { - sql_print_information("Failed to delete file '%s'; " + sql_print_information("Failed to delete file '%s' and " + "read the binlog index file", + log_info.log_file_name); + } + goto err; + } + + error= 0; + if (!need_mutex) + { + /* + This is to avoid triggering an error in NDB. + */ + ha_binlog_index_purge_file(current_thd, log_info.log_file_name); + } + + DBUG_PRINT("info",("purging %s",log_info.log_file_name)); + if (!my_delete(log_info.log_file_name, MYF(0))) + { + if (decrease_log_space) + *decrease_log_space-= s.st_size; + } + else + { + if (my_errno == ENOENT) + { + if (thd) + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE), + log_info.log_file_name); + } + sql_print_information("Failed to delete file '%s'", + log_info.log_file_name); + my_errno= 0; + } + else + { + if (thd) + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_BINLOG_PURGE_FATAL_ERR, + "a problem with deleting %s; " "consider examining correspondence " "of your binlog index file " "to the actual binlog files", log_info.log_file_name); - } - if (my_errno == EMFILE) - { - DBUG_PRINT("info", - ("my_errno: %d, set ret = LOG_INFO_EMFILE", my_errno)); - error= LOG_INFO_EMFILE; + } + else + { + sql_print_information("Failed to delete file '%s'; " + "consider examining correspondence " + "of your binlog index file " + "to the actual binlog files", + log_info.log_file_name); + } + if (my_errno == EMFILE) + { + DBUG_PRINT("info", + ("my_errno: %d, set ret = LOG_INFO_EMFILE", my_errno)); + error= LOG_INFO_EMFILE; + goto err; + } + error= LOG_INFO_FATAL; goto err; } - error= LOG_INFO_FATAL; - goto err; } } } } err: - close_cached_file(&purge_temp); - if (need_mutex) - pthread_mutex_unlock(&LOCK_index); DBUG_RETURN(error); } @@ -3407,7 +3628,8 @@ int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time) goto err; while (strcmp(log_file_name, log_info.log_file_name) && - !log_in_use(log_info.log_file_name)) + !is_active(log_info.log_file_name) && + !log_in_use(log_info.log_file_name)) { if (!my_stat(log_info.log_file_name, &stat_area, MYF(0))) { @@ -3416,14 +3638,6 @@ int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time) /* It's not fatal if we can't stat a log file that does not exist. */ - if (thd) - { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_LOG_PURGE_NO_FILE, ER(ER_LOG_PURGE_NO_FILE), - log_info.log_file_name); - } - sql_print_information("Failed to execute my_stat on file '%s'", - log_info.log_file_name); my_errno= 0; } else @@ -3618,9 +3832,9 @@ void MYSQL_BIN_LOG::new_file_impl(bool need_lock) */ /* reopen index binlog file, BUG#34582 */ - if (!open_index_file(index_file_name, 0)) - open(old_name, log_type, new_name_ptr, - io_cache_type, no_auto_events, max_size, 1); + if (!open_index_file(index_file_name, 0, FALSE)) + open(old_name, log_type, new_name_ptr, + io_cache_type, no_auto_events, max_size, 1, FALSE); my_free(old_name,MYF(0)); end: @@ -5522,7 +5736,7 @@ int TC_LOG_BINLOG::open(const char *opt_name) if (using_heuristic_recover()) { /* generate a new binlog to mask a corrupted one */ - open(opt_name, LOG_BIN, 0, WRITE_CACHE, 0, max_binlog_size, 0); + open(opt_name, LOG_BIN, 0, WRITE_CACHE, 0, max_binlog_size, 0, TRUE); cleanup(); return 1; } diff --git a/sql/log.h b/sql/log.h index d306d6f7182..8b5dfcb3935 100644 --- a/sql/log.h +++ b/sql/log.h @@ -172,6 +172,10 @@ public: enum_log_type log_type, const char *new_name, enum cache_type io_cache_type_arg); + bool init_and_set_log_file_name(const char *log_name, + const char *new_name, + enum_log_type log_type_arg, + enum cache_type io_cache_type_arg); void init(enum_log_type log_type_arg, enum cache_type io_cache_type_arg); void close(uint exiting); @@ -233,14 +237,15 @@ class MYSQL_BIN_LOG: public TC_LOG, private MYSQL_LOG pthread_cond_t update_cond; ulonglong bytes_written; IO_CACHE index_file; + char index_file_name[FN_REFLEN]; /* - purge_temp is a temp file used in purge_logs so that the index file + purge_file is a temp file used in purge_logs so that the index file can be updated before deleting files from disk, yielding better crash recovery. It is created on demand the first time purge_logs is called and then reused for subsequent calls. It is cleaned up in cleanup(). */ - IO_CACHE purge_temp; - char index_file_name[FN_REFLEN]; + IO_CACHE purge_index_file; + char purge_index_file_name[FN_REFLEN]; /* The max size before rotation (usable only if log_type == LOG_BIN: binary logs and relay logs). @@ -349,9 +354,10 @@ public: const char *new_name, enum cache_type io_cache_type_arg, bool no_auto_events_arg, ulong max_size, - bool null_created); + bool null_created, + bool need_mutex); bool open_index_file(const char *index_file_name_arg, - const char *log_name); + const char *log_name, bool need_mutex); /* Use this to start writing a new log file */ void new_file(); @@ -384,6 +390,16 @@ public: ulonglong *decrease_log_space); int purge_logs_before_date(time_t purge_time); int purge_first_log(Relay_log_info* rli, bool included); + int set_purge_index_file_name(const char *base_file_name); + int open_purge_index_file(bool destroy); + bool is_inited_purge_index_file(); + int close_purge_index_file(); + int clean_purge_index_file(); + int sync_purge_index_file(); + int register_purge_index_entry(const char* entry); + int register_create_index_entry(const char* entry); + int purge_index_entry(THD *thd, ulonglong *decrease_log_space, + bool need_mutex); bool reset_logs(THD* thd); void close(uint exiting); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5c643b03798..de532e92fda 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3932,7 +3932,7 @@ a file name for --log-bin-index option", opt_binlog_index_name); my_free(opt_bin_logname, MYF(MY_ALLOW_ZERO_PTR)); opt_bin_logname=my_strdup(buf, MYF(0)); } - if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln)) + if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln, TRUE)) { unireg_abort(1); } @@ -4096,7 +4096,7 @@ a file name for --log-bin-index option", opt_binlog_index_name); } if (opt_bin_log && mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0, - WRITE_CACHE, 0, max_binlog_size, 0)) + WRITE_CACHE, 0, max_binlog_size, 0, TRUE)) unireg_abort(1); #ifdef HAVE_REPLICATION diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index a26717d7acf..66de9357a53 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -182,10 +182,10 @@ a file name for --relay-log-index option", opt_relaylog_index_name); note, that if open() fails, we'll still have index file open but a destructor will take care of that */ - if (rli->relay_log.open_index_file(opt_relaylog_index_name, ln) || + if (rli->relay_log.open_index_file(opt_relaylog_index_name, ln, TRUE) || rli->relay_log.open(ln, LOG_BIN, 0, SEQ_READ_APPEND, 0, (max_relay_log_size ? max_relay_log_size : - max_binlog_size), 1)) + max_binlog_size), 1, TRUE)) { pthread_mutex_unlock(&rli->data_lock); sql_print_error("Failed in open_log() called from init_relay_log_info()"); From 4760c13e029d12cf9bdb2688e23b57b3c3c6fa36 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 4 Dec 2009 14:00:20 -0200 Subject: [PATCH 016/157] Bug#41569: mysql_upgrade (ver 5.1) add 3 fields to mysql.proc table but does not set values Post-merge fix: Redirect stderr to a file as to avoid buffering problems due to redirecting stderr to stdout. mysql-test/r/mysql_upgrade.result: Update test case result. mysql-test/t/mysql_upgrade.test: Redirect stderr to a file, cat and remove. --- mysql-test/r/mysql_upgrade.result | 6 +++--- mysql-test/t/mysql_upgrade.test | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/mysql_upgrade.result b/mysql-test/r/mysql_upgrade.result index 72917988594..821ad31871f 100644 --- a/mysql-test/r/mysql_upgrade.result +++ b/mysql-test/r/mysql_upgrade.result @@ -135,9 +135,6 @@ CREATE PROCEDURE testproc() BEGIN END; UPDATE mysql.proc SET character_set_client = NULL WHERE name LIKE 'testproc'; UPDATE mysql.proc SET collation_connection = NULL WHERE name LIKE 'testproc'; UPDATE mysql.proc SET db_collation = NULL WHERE name LIKE 'testproc'; -WARNING: NULL values of the 'character_set_client' column ('mysql.proc' table) have been updated with a default value (latin1). Please verify if necessary. -WARNING: NULL values of the 'collation_connection' column ('mysql.proc' table) have been updated with a default value (latin1_swedish_ci). Please verify if necessary. -WARNING: NULL values of the 'db_collation' column ('mysql.proc' table) have been updated with default values. Please verify if necessary. mtr.global_suppressions OK mtr.test_suppressions OK mysql.columns_priv OK @@ -169,3 +166,6 @@ mysql.time_zone_transition_type OK mysql.user OK CALL testproc(); DROP PROCEDURE testproc; +WARNING: NULL values of the 'character_set_client' column ('mysql.proc' table) have been updated with a default value (latin1). Please verify if necessary. +WARNING: NULL values of the 'collation_connection' column ('mysql.proc' table) have been updated with a default value (latin1_swedish_ci). Please verify if necessary. +WARNING: NULL values of the 'db_collation' column ('mysql.proc' table) have been updated with default values. Please verify if necessary. diff --git a/mysql-test/t/mysql_upgrade.test b/mysql-test/t/mysql_upgrade.test index 937c9d7a212..24a1d2e1b5d 100644 --- a/mysql-test/t/mysql_upgrade.test +++ b/mysql-test/t/mysql_upgrade.test @@ -103,6 +103,8 @@ CREATE PROCEDURE testproc() BEGIN END; UPDATE mysql.proc SET character_set_client = NULL WHERE name LIKE 'testproc'; UPDATE mysql.proc SET collation_connection = NULL WHERE name LIKE 'testproc'; UPDATE mysql.proc SET db_collation = NULL WHERE name LIKE 'testproc'; ---exec $MYSQL_UPGRADE --skip-verbose --force 2>&1 +--exec $MYSQL_UPGRADE --skip-verbose --force 2> $MYSQLTEST_VARDIR/tmp/41569.txt CALL testproc(); DROP PROCEDURE testproc; +--cat_file $MYSQLTEST_VARDIR/tmp/41569.txt +--remove_file $MYSQLTEST_VARDIR/tmp/41569.txt From e53ecf2dc241a29a2ef732850ff77d4896de4412 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 4 Dec 2009 13:36:58 -0200 Subject: [PATCH 017/157] Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0 The problem was that the multiple evaluations of a ENCODE or DECODE function within a single statement caused the random generator to be reinitialized at each evaluation, even though the parameters were constants. The solution is to initialize the random generator only once if the password (seed) parameter is constant. This patch borrows code and ideas from Georgi Kodinov's patch. mysql-test/r/func_str.result: Add test case result. mysql-test/r/ps.result: Add test case result. mysql-test/t/func_str.test: Add test case for Bug#49141 mysql-test/t/ps.test: Add test case for Bug#49141 sql/item_strfunc.cc: Move seed generation code to a separate method. Seed only once if the password (seed) argument is constant. Remove duplicated code and use a transform method to apply encoding or decoding. sql/item_strfunc.h: Add parameter to signal whether the PRNG is already seeded. Introduce transform method. Combine val_str methods. sql/sql_crypt.cc: Remove method. sql/sql_crypt.h: Seed is supplied as two long integers. --- mysql-test/r/func_str.result | 29 +++++++++++++++ mysql-test/r/ps.result | 19 ++++++++++ mysql-test/t/func_str.test | 34 +++++++++++++++++ mysql-test/t/ps.test | 16 ++++++++ sql/item_strfunc.cc | 71 +++++++++++++++++------------------- sql/item_strfunc.h | 13 ++++++- sql/sql_crypt.cc | 9 +---- sql/sql_crypt.h | 8 ++-- 8 files changed, 149 insertions(+), 50 deletions(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 2a2fe50ad0f..d144e84dfdc 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -2558,3 +2558,32 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ALL NULL NULL NULL NULL 2 Using join buffer 2 DERIVED t1 ALL NULL NULL NULL NULL 2 drop table t1; +# +# Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0 +# +DROP TABLE IF EXISTS t1, t2; +CREATE TABLE t1 (a VARCHAR(20), b INT); +CREATE TABLE t2 (a VARCHAR(20), b INT); +INSERT INTO t1 VALUES ('ABC', 1); +INSERT INTO t2 VALUES ('ABC', 1); +SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a) +FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b; +DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a) +secret +SELECT DECODE((SELECT ENCODE('secret', 'ABC') FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a) +FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b; +DECODE((SELECT ENCODE('secret', 'ABC') FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a) +secret +SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), 'ABC') +FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b; +DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), 'ABC') +secret +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; +INSERT INTO t1 VALUES ('EDF', 3), ('BCD', 2), ('ABC', 1); +INSERT INTO t2 VALUES ('EDF', 3), ('BCD', 2), ('ABC', 1); +SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b LIMIT 1), t2.a) +FROM t2 WHERE t2.b = 1 GROUP BY t2.b; +DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b LIMIT 1), t2.a) +secret +DROP TABLE t1, t2; diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index f64d58ff8f4..c26a324d00b 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -2947,4 +2947,23 @@ execute stmt; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation drop table t1; deallocate prepare stmt; +# +# Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0 +# +prepare encode from "select encode(?, ?) into @ciphertext"; +prepare decode from "select decode(?, ?) into @plaintext"; +set @str="abc", @key="cba"; +execute encode using @str, @key; +execute decode using @ciphertext, @key; +select @plaintext; +@plaintext +abc +set @str="bcd", @key="dcb"; +execute encode using @str, @key; +execute decode using @ciphertext, @key; +select @plaintext; +@plaintext +bcd +deallocate prepare encode; +deallocate prepare decode; End of 5.1 tests. diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 66b9eabd385..8942b0a2faf 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -1318,3 +1318,37 @@ insert into t1 values (-1),(null); explain select 1 as a from t1,(select decode(f1,f1) as b from t1) a; explain select 1 as a from t1,(select encode(f1,f1) as b from t1) a; drop table t1; + +--echo # +--echo # Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0 +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1, t2; +--enable_warnings + +CREATE TABLE t1 (a VARCHAR(20), b INT); +CREATE TABLE t2 (a VARCHAR(20), b INT); + +INSERT INTO t1 VALUES ('ABC', 1); +INSERT INTO t2 VALUES ('ABC', 1); + +SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a) + FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b; + +SELECT DECODE((SELECT ENCODE('secret', 'ABC') FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), t2.a) + FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b; + +SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b), 'ABC') + FROM t1,t2 WHERE t1.b = t1.b > 0 GROUP BY t2.b; + +TRUNCATE TABLE t1; +TRUNCATE TABLE t2; + +INSERT INTO t1 VALUES ('EDF', 3), ('BCD', 2), ('ABC', 1); +INSERT INTO t2 VALUES ('EDF', 3), ('BCD', 2), ('ABC', 1); + +SELECT DECODE((SELECT ENCODE('secret', t1.a) FROM t1,t2 WHERE t1.a = t2.a GROUP BY t1.b LIMIT 1), t2.a) + FROM t2 WHERE t2.b = 1 GROUP BY t2.b; + +DROP TABLE t1, t2; diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 4870f4836df..b0930a42b41 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -3032,5 +3032,21 @@ execute stmt; drop table t1; deallocate prepare stmt; +--echo # +--echo # Bug#49141: Encode function is significantly slower in 5.1 compared to 5.0 +--echo # + +prepare encode from "select encode(?, ?) into @ciphertext"; +prepare decode from "select decode(?, ?) into @plaintext"; +set @str="abc", @key="cba"; +execute encode using @str, @key; +execute decode using @ciphertext, @key; +select @plaintext; +set @str="bcd", @key="dcb"; +execute encode using @str, @key; +execute decode using @ciphertext, @key; +select @plaintext; +deallocate prepare encode; +deallocate prepare decode; --echo End of 5.1 tests. diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 183a628f8e4..b6d3f45f4c2 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1720,68 +1720,65 @@ String *Item_func_encrypt::val_str(String *str) #endif /* HAVE_CRYPT */ } +bool Item_func_encode::seed() +{ + char buf[80]; + ulong rand_nr[2]; + String *key, tmp(buf, sizeof(buf), system_charset_info); + + if (!(key= args[1]->val_str(&tmp))) + return TRUE; + + hash_password(rand_nr, key->ptr(), key->length()); + sql_crypt.init(rand_nr); + + return FALSE; +} + void Item_func_encode::fix_length_and_dec() { max_length=args[0]->max_length; maybe_null=args[0]->maybe_null || args[1]->maybe_null; collation.set(&my_charset_bin); + /* Precompute the seed state if the item is constant. */ + seeded= args[1]->const_item() && + (args[1]->result_type() == STRING_RESULT) && !seed(); } String *Item_func_encode::val_str(String *str) { String *res; - char pw_buff[80]; - String tmp_pw_value(pw_buff, sizeof(pw_buff), system_charset_info); - String *password; DBUG_ASSERT(fixed == 1); if (!(res=args[0]->val_str(str))) { - null_value=1; /* purecov: inspected */ - return 0; /* purecov: inspected */ + null_value= 1; + return NULL; } - if (!(password=args[1]->val_str(& tmp_pw_value))) + if (!seeded && seed()) { - null_value=1; - return 0; + null_value= 1; + return NULL; } - null_value=0; - res=copy_if_not_alloced(str,res,res->length()); - SQL_CRYPT sql_crypt(password->ptr(), password->length()); - sql_crypt.init(); - sql_crypt.encode((char*) res->ptr(),res->length()); - res->set_charset(&my_charset_bin); + null_value= 0; + res= copy_if_not_alloced(str, res, res->length()); + transform(res); + sql_crypt.reinit(); + return res; } -String *Item_func_decode::val_str(String *str) +void Item_func_encode::transform(String *res) { - String *res; - char pw_buff[80]; - String tmp_pw_value(pw_buff, sizeof(pw_buff), system_charset_info); - String *password; - DBUG_ASSERT(fixed == 1); + sql_crypt.encode((char*) res->ptr(),res->length()); + res->set_charset(&my_charset_bin); +} - if (!(res=args[0]->val_str(str))) - { - null_value=1; /* purecov: inspected */ - return 0; /* purecov: inspected */ - } - - if (!(password=args[1]->val_str(& tmp_pw_value))) - { - null_value=1; - return 0; - } - - null_value=0; - res=copy_if_not_alloced(str,res,res->length()); - SQL_CRYPT sql_crypt(password->ptr(), password->length()); - sql_crypt.init(); +void Item_func_decode::transform(String *res) +{ sql_crypt.decode((char*) res->ptr(),res->length()); - return res; } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 2cdb45100ae..59241872e63 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -351,12 +351,22 @@ public: class Item_func_encode :public Item_str_func { +private: + /** Whether the PRNG has already been seeded. */ + bool seeded; +protected: + SQL_CRYPT sql_crypt; public: Item_func_encode(Item *a, Item *seed): Item_str_func(a, seed) {} String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "encode"; } +protected: + virtual void transform(String *); +private: + /** Provide a seed for the PRNG sequence. */ + bool seed(); }; @@ -364,8 +374,9 @@ class Item_func_decode :public Item_func_encode { public: Item_func_decode(Item *a, Item *seed): Item_func_encode(a, seed) {} - String *val_str(String *); const char *func_name() const { return "decode"; } +protected: + void transform(String *); }; diff --git a/sql/sql_crypt.cc b/sql/sql_crypt.cc index c4f93cc2a33..3d7d248782b 100644 --- a/sql/sql_crypt.cc +++ b/sql/sql_crypt.cc @@ -28,14 +28,7 @@ #include "mysql_priv.h" -SQL_CRYPT::SQL_CRYPT(const char *password, uint length) -{ - ulong rand_nr[2]; - hash_password(rand_nr,password, length); - crypt_init(rand_nr); -} - -void SQL_CRYPT::crypt_init(ulong *rand_nr) +void SQL_CRYPT::init(ulong *rand_nr) { uint i; randominit(&rand,rand_nr[0],rand_nr[1]); diff --git a/sql/sql_crypt.h b/sql/sql_crypt.h index a5a6bee8a58..2b56c387bd1 100644 --- a/sql/sql_crypt.h +++ b/sql/sql_crypt.h @@ -23,15 +23,15 @@ class SQL_CRYPT :public Sql_alloc struct rand_struct rand,org_rand; char decode_buff[256],encode_buff[256]; uint shift; - void crypt_init(ulong *seed); public: - SQL_CRYPT(const char *seed, uint length); + SQL_CRYPT() {} SQL_CRYPT(ulong *seed) { - crypt_init(seed); + init(seed); } ~SQL_CRYPT() {} - void init() { shift=0; rand=org_rand; } + void init(ulong *seed); + void reinit() { shift=0; rand=org_rand; } void encode(char *str, uint length); void decode(char *str, uint length); }; From f5b51bc1e29d0ae9d8ba9ec7d1c500fe09915e74 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 4 Dec 2009 21:58:40 +0400 Subject: [PATCH 018/157] Fix for bug#49199: Optimizer handles incorrectly: field='const1' AND field='const2' in some cases Building multiple equality predicates containing a constant which is compared as a datetime (with a field) we should take this fact into account and compare the constant with another possible constatns as datetimes as well. E.g. for the SELECT ... WHERE a='2001-01-01' AND a='2001-01-01 00:00:00' we should compare '2001-01-01' with '2001-01-01 00:00:00' as datetimes but not as strings. mysql-test/r/select.result: Fix for bug#49199: Optimizer handles incorrectly: field='const1' AND field='const2' in some cases - test result. mysql-test/t/select.test: Fix for bug#49199: Optimizer handles incorrectly: field='const1' AND field='const2' in some cases - test case. sql/item_cmpfunc.cc: Fix for bug#49199: Optimizer handles incorrectly: field='const1' AND field='const2' in some cases - adding a constant to Item_equal compare it as a datetime value with stored one if there's a date[time] field in a equality predicate. sql/item_cmpfunc.h: Fix for bug#49199: Optimizer handles incorrectly: field='const1' AND field='const2' in some cases - adding a constant to Item_equal compare it as a datetime value with stored one if there's a date[time] field in a equality predicate. sql/sql_select.cc: Fix for bug#49199: Optimizer handles incorrectly: field='const1' AND field='const2' in some cases - adding a constant to Item_equal compare it as a datetime value with stored one if there's a date[time] field in a equality predicate. --- mysql-test/r/select.result | 84 ++++++++++++++++++++++++++++++++++++++ mysql-test/t/select.test | 49 ++++++++++++++++++++++ sql/item_cmpfunc.cc | 46 ++++++++++++++++++--- sql/item_cmpfunc.h | 4 ++ sql/sql_select.cc | 2 +- 5 files changed, 178 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index ff59eadab0c..1b2533eec89 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4456,4 +4456,88 @@ SELECT 1 FROM t2 JOIN t1 ON 1=1 WHERE a != '1' AND NOT a >= b OR NOT ROW(b,a )<> ROW(a,a); 1 DROP TABLE t1,t2; +# +# Bug #49199: Optimizer handles incorrectly: +# field='const1' AND field='const2' in some cases + +CREATE TABLE t1(a DATETIME NOT NULL); +INSERT INTO t1 VALUES('2001-01-01'); +SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +a +2001-01-01 00:00:00 +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 +Warnings: +Note 1003 select '2001-01-01 00:00:00' AS `a` from `test`.`t1` where 1 +DROP TABLE t1; +CREATE TABLE t1(a DATE NOT NULL); +INSERT INTO t1 VALUES('2001-01-01'); +SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +a +2001-01-01 +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 +Warnings: +Note 1003 select '2001-01-01' AS `a` from `test`.`t1` where 1 +DROP TABLE t1; +CREATE TABLE t1(a TIMESTAMP NOT NULL); +INSERT INTO t1 VALUES('2001-01-01'); +SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +a +2001-01-01 00:00:00 +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 +Warnings: +Note 1003 select '2001-01-01 00:00:00' AS `a` from `test`.`t1` where 1 +DROP TABLE t1; +CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL); +INSERT INTO t1 VALUES('2001-01-01', '2001-01-01'); +SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00'; +a b +2001-01-01 00:00:00 2001-01-01 +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 +Warnings: +Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 1 +DROP TABLE t1; +CREATE TABLE t1(a DATETIME NOT NULL, b VARCHAR(20) NOT NULL); +INSERT INTO t1 VALUES('2001-01-01', '2001-01-01'); +SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00'; +a b +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 0 +SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01'; +a b +2001-01-01 00:00:00 2001-01-01 +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 +Warnings: +Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01' AS `b` from `test`.`t1` where 1 +DROP TABLE t1; +CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL); +INSERT INTO t1 VALUES('2001-01-01', '2001-01-01'); +SELECT x.a, y.a, z.a FROM t1 x +JOIN t1 y ON x.a=y.a +JOIN t1 z ON y.a=z.a +WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00'; +a a a +2001-01-01 00:00:00 2001-01-01 00:00:00 2001-01-01 00:00:00 +EXPLAIN EXTENDED SELECT x.a, y.a, z.a FROM t1 x +JOIN t1 y ON x.a=y.a +JOIN t1 z ON y.a=z.a +WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE x system NULL NULL NULL NULL 1 +1 SIMPLE y system NULL NULL NULL NULL 1 +1 SIMPLE z system NULL NULL NULL NULL 1 +Warnings: +Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01 00:00:00' AS `a`,'2001-01-01 00:00:00' AS `a` from `test`.`t1` `x` join `test`.`t1` `y` join `test`.`t1` `z` where 1 End of 5.0 tests diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index a4d3056b66e..eeabd2641d8 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -3797,4 +3797,53 @@ SELECT 1 FROM t2 JOIN t1 ON 1=1 DROP TABLE t1,t2; +--echo # +--echo # Bug #49199: Optimizer handles incorrectly: +--echo # field='const1' AND field='const2' in some cases +--echo +CREATE TABLE t1(a DATETIME NOT NULL); +INSERT INTO t1 VALUES('2001-01-01'); +SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +DROP TABLE t1; + +CREATE TABLE t1(a DATE NOT NULL); +INSERT INTO t1 VALUES('2001-01-01'); +SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +DROP TABLE t1; + +CREATE TABLE t1(a TIMESTAMP NOT NULL); +INSERT INTO t1 VALUES('2001-01-01'); +SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a='2001-01-01 00:00:00'; +DROP TABLE t1; + +CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL); +INSERT INTO t1 VALUES('2001-01-01', '2001-01-01'); +SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00'; +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00'; +DROP TABLE t1; + +CREATE TABLE t1(a DATETIME NOT NULL, b VARCHAR(20) NOT NULL); +INSERT INTO t1 VALUES('2001-01-01', '2001-01-01'); +SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00'; +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01' AND a=b AND b='2001-01-01 00:00:00'; + +SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01'; +EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='2001-01-01 00:00:00' AND a=b AND b='2001-01-01'; +DROP TABLE t1; + +CREATE TABLE t1(a DATETIME NOT NULL, b DATE NOT NULL); +INSERT INTO t1 VALUES('2001-01-01', '2001-01-01'); +SELECT x.a, y.a, z.a FROM t1 x + JOIN t1 y ON x.a=y.a + JOIN t1 z ON y.a=z.a + WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00'; +EXPLAIN EXTENDED SELECT x.a, y.a, z.a FROM t1 x + JOIN t1 y ON x.a=y.a + JOIN t1 z ON y.a=z.a + WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00'; + + --echo End of 5.0 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index d03c68b3560..5c2fb9857d5 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -4903,7 +4903,8 @@ Item *Item_bool_rowready_func2::negated_item() } Item_equal::Item_equal(Item_field *f1, Item_field *f2) - : Item_bool_func(), const_item(0), eval_item(0), cond_false(0) + : Item_bool_func(), const_item(0), eval_item(0), cond_false(0), + compare_as_dates(FALSE) { const_item_cache= 0; fields.push_back(f1); @@ -4916,6 +4917,7 @@ Item_equal::Item_equal(Item *c, Item_field *f) const_item_cache= 0; fields.push_back(f); const_item= c; + compare_as_dates= f->is_datetime(); } @@ -4930,9 +4932,45 @@ Item_equal::Item_equal(Item_equal *item_equal) fields.push_back(item); } const_item= item_equal->const_item; + compare_as_dates= item_equal->compare_as_dates; cond_false= item_equal->cond_false; } + +void Item_equal::compare_const(Item *c) +{ + if (compare_as_dates) + { + cmp.set_datetime_cmp_func(&c, &const_item); + cond_false= cmp.compare(); + } + else + { + Item_func_eq *func= new Item_func_eq(c, const_item); + func->set_cmp_func(); + func->quick_fix_field(); + cond_false= !func->val_int(); + } + if (cond_false) + const_item_cache= 1; +} + + +void Item_equal::add(Item *c, Item_field *f) +{ + if (cond_false) + return; + if (!const_item) + { + DBUG_ASSERT(f); + const_item= c; + compare_as_dates= f->is_datetime(); + return; + } + compare_const(c); +} + + void Item_equal::add(Item *c) { if (cond_false) @@ -4942,11 +4980,7 @@ void Item_equal::add(Item *c) const_item= c; return; } - Item_func_eq *func= new Item_func_eq(c, const_item); - func->set_cmp_func(); - func->quick_fix_field(); - if ((cond_false= !func->val_int())) - const_item_cache= 1; + compare_const(c); } void Item_equal::add(Item_field *f) diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index db831c7030c..89bc6f9570b 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1477,7 +1477,9 @@ class Item_equal: public Item_bool_func List fields; /* list of equal field items */ Item *const_item; /* optional constant item equal to fields items */ cmp_item *eval_item; + Arg_comparator cmp; bool cond_false; + bool compare_as_dates; public: inline Item_equal() : Item_bool_func(), const_item(0), eval_item(0), cond_false(0) @@ -1486,6 +1488,8 @@ public: Item_equal(Item *c, Item_field *f); Item_equal(Item_equal *item_equal); inline Item* get_const() { return const_item; } + void compare_const(Item *c); + void add(Item *c, Item_field *f); void add(Item *c); void add(Item_field *f); uint members(); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index df7c5af3ebc..9f0843fe0db 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7237,7 +7237,7 @@ static bool check_simple_equality(Item *left_item, Item *right_item, already contains a constant and its value is not equal to the value of const_item. */ - item_equal->add(const_item); + item_equal->add(const_item, field_item); } else { From 24e1b16bc280c21de61287f07c3c02bc89387601 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Sat, 5 Dec 2009 22:09:41 +0000 Subject: [PATCH 019/157] Post-push fix for BUG#45292. --- mysql-test/suite/binlog/t/binlog_index.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/suite/binlog/t/binlog_index.test b/mysql-test/suite/binlog/t/binlog_index.test index 8e54c028dbd..6bfa625422c 100644 --- a/mysql-test/suite/binlog/t/binlog_index.test +++ b/mysql-test/suite/binlog/t/binlog_index.test @@ -3,6 +3,7 @@ # source include/have_log_bin.inc; source include/not_embedded.inc; +source include/have_debug.inc; call mtr.add_suppression('Attempting backtrace'); call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to process registered files that would be purged.'); call mtr.add_suppression('MSYQL_BIN_LOG::open failed to sync the index file'); From 595719280eeec7dc9dda340d001de72a728b0ed1 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Sun, 6 Dec 2009 01:11:32 +0000 Subject: [PATCH 020/157] BUG#49479: Slave stops with syntax error: LOAD DATA event without escaped field names When in mixed or statement mode, the master logs LOAD DATA queries by resorting to an Execute_load_query_log_event. This event does not contain the original query, but a rewritten version of it, which includes the table field names. However, the rewrite does not escape the field names. If these names match a reserved keyword, then the slave will stop with a syntax error when executing the event. We fix this by escaping the fields names as it happens already for the table name. mysql-test/extra/rpl_tests/rpl_loaddata.test: Added test case for the reported bug. mysql-test/r/mysqlbinlog.result: Changed result to support escaped field name. mysql-test/suite/binlog/r/binlog_killed_simulate.result: Changed result to support escaped field name. mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result: Changed result to support escaped field name. mysql-test/suite/binlog/r/binlog_stm_blackhole.result: Changed result to support escaped field name. mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result: Changed result to support escaped field name. mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result: Changed result to support escaped field name. mysql-test/suite/rpl/r/rpl_loaddata.result: Added result for new test. Changed show slave status positions which are now different because of extra escape character in field names. mysql-test/suite/rpl/r/rpl_loaddata_fatal.result: Changed show slave status positions which are now different because of extra escape character. mysql-test/suite/rpl/r/rpl_loaddata_map.result: Changed result to support escaped field name. mysql-test/suite/rpl/r/rpl_stm_log.result: Changed result to support escaped field name. mysql-test/t/mysqlbinlog.test: Changed positions which is now different because of extra escape character in field names. sql/sql_load.cc: Appended escape characters before and after field names. --- mysql-test/extra/rpl_tests/rpl_loaddata.test | 14 +++++++++ mysql-test/r/mysqlbinlog.result | 30 +++++++++---------- .../binlog/r/binlog_killed_simulate.result | 2 +- .../r/binlog_row_mix_innodb_myisam.result | 2 +- .../binlog/r/binlog_stm_blackhole.result | 2 +- .../r/binlog_stm_mix_innodb_myisam.result | 4 +-- .../suite/rpl/r/rpl_innodb_mixed_dml.result | 2 +- mysql-test/suite/rpl/r/rpl_loaddata.result | 21 +++++++++++-- .../suite/rpl/r/rpl_loaddata_fatal.result | 2 +- .../suite/rpl/r/rpl_loaddata_map.result | 2 +- mysql-test/suite/rpl/r/rpl_stm_log.result | 6 ++-- mysql-test/t/mysqlbinlog.test | 4 +-- sql/sql_load.cc | 6 ++++ 13 files changed, 67 insertions(+), 30 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_loaddata.test b/mysql-test/extra/rpl_tests/rpl_loaddata.test index 7db12600456..649337b2a24 100644 --- a/mysql-test/extra/rpl_tests/rpl_loaddata.test +++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test @@ -219,4 +219,18 @@ source include/diff_tables.inc; -- sync_slave_with_master +# BUG#49479: LOAD DATA INFILE is binlogged without escaping field names +-- source include/master-slave-reset.inc +-- connection master +use test; +CREATE TABLE t1 (`key` TEXT, `text` TEXT); + +LOAD DATA INFILE '../../std_data/loaddata2.dat' REPLACE INTO TABLE `t1` FIELDS TERMINATED BY ','; +SELECT * FROM t1; + +-- sync_slave_with_master +-- connection master +DROP TABLE t1; +-- sync_slave_with_master + # End of 4.1 tests diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index 5f32561798b..9d4fde96d18 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -44,16 +44,16 @@ SET TIMESTAMP=1000000000/*!*/; insert into t2 values () /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`) /*!*/; DELIMITER ; # End of log file @@ -144,16 +144,16 @@ SET TIMESTAMP=1000000000/*!*/; insert into t2 values () /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`) /*!*/; DELIMITER ; # End of log file @@ -359,29 +359,29 @@ SET @@session.collation_database=DEFAULT/*!*/; create table t1 (a varchar(64) character set utf8) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) /*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.collation_database=7/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) /*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.collation_database=DEFAULT/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) /*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.collation_database=7/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-a-0' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-a-0' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) /*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.collation_database=DEFAULT/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-b-0' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-b-0' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-c-0' INTO TABLE `t1` CHARACTER SET koi8r FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-c-0' INTO TABLE `t1` CHARACTER SET koi8r FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) /*!*/; SET TIMESTAMP=1000000000/*!*/; drop table t1 diff --git a/mysql-test/suite/binlog/r/binlog_killed_simulate.result b/mysql-test/suite/binlog/r/binlog_killed_simulate.result index df04f5129cf..0e1b5c92d57 100644 --- a/mysql-test/suite/binlog/r/binlog_killed_simulate.result +++ b/mysql-test/suite/binlog/r/binlog_killed_simulate.result @@ -19,7 +19,7 @@ ERROR 70100: Query execution was interrupted show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, b) ;file_id=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, `b`) ;file_id=# select (@a:=load_file("MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog")) is not null; diff --git a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result index 4ccc3b5e797..ef98275041c 100644 --- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result @@ -929,7 +929,7 @@ master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# master-bin.000001 # Intvar # # INSERT_ID=10 master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, @b) SET b=((@b) + `bug27417`(2)) ;file_id=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=# master-bin.000001 # Query # # ROLLBACK drop trigger trg_del_t2; drop table t1,t2,t3,t4,t5; diff --git a/mysql-test/suite/binlog/r/binlog_stm_blackhole.result b/mysql-test/suite/binlog/r/binlog_stm_blackhole.result index 434c1b0896f..b2e6ac854cf 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_blackhole.result +++ b/mysql-test/suite/binlog/r/binlog_stm_blackhole.result @@ -127,7 +127,7 @@ master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; create table t2 (a varchar(200)) engine=blackhole master-bin.000001 # Query # # BEGIN master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=581 -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) ;file_id=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) ;file_id=# master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; alter table t1 add b int master-bin.000001 # Query # # use `test`; alter table t1 drop b diff --git a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result index de83c7a873d..e2f29295383 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result @@ -628,7 +628,7 @@ master-bin.000001 # Query # # BEGIN master-bin.000001 # Intvar # # INSERT_ID=10 master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# master-bin.000001 # Intvar # # INSERT_ID=10 -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, @b) SET b=((@b) + `bug27417`(2)) ;file_id=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=# master-bin.000001 # Query # # ROLLBACK /* the output must denote there is the query */; drop trigger trg_del_t2; @@ -866,7 +866,7 @@ master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# master-bin.000001 # Intvar # # INSERT_ID=10 master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, @b) SET b=((@b) + `bug27417`(2)) ;file_id=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=# master-bin.000001 # Query # # ROLLBACK drop trigger trg_del_t2; drop table t1,t2,t3,t4,t5; diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result index 3a1c2b68b01..fbfebbaa590 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result @@ -885,7 +885,7 @@ master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Begin_load_query 1 # ;file_id=#;block_len=# -master-bin.000001 # Execute_load_query 1 # use `test_rpl`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/std_data/rpl_mixed.dat' INTO TABLE `t1` FIELDS TERMINATED BY '|' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, b) ;file_id=# +master-bin.000001 # Execute_load_query 1 # use `test_rpl`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/std_data/rpl_mixed.dat' INTO TABLE `t1` FIELDS TERMINATED BY '|' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, `b`) ;file_id=# master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 diff --git a/mysql-test/suite/rpl/r/rpl_loaddata.result b/mysql-test/suite/rpl/r/rpl_loaddata.result index ca9c14691b0..5c6a67d6f3c 100644 --- a/mysql-test/suite/rpl/r/rpl_loaddata.result +++ b/mysql-test/suite/rpl/r/rpl_loaddata.result @@ -36,7 +36,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 Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 2009 # # master-bin.000001 Yes Yes # 0 0 2009 # None 0 No # No 0 0 +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 2025 # # master-bin.000001 Yes Yes # 0 0 2025 # None 0 No # No 0 0 set sql_log_bin=0; delete from t1; set sql_log_bin=1; @@ -46,7 +46,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 Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 2044 # # master-bin.000001 No No # 0 0 2044 # None 0 No # No 0 0 +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 2060 # # master-bin.000001 No No # 0 0 2060 # None 0 No # No 0 0 set global sql_slave_skip_counter=1; start slave; set sql_log_bin=0; @@ -115,3 +115,20 @@ use b48297_db1; Comparing tables master:b48297_db1.t1 and slave:b48297_db1.t1 DROP DATABASE b48297_db1; DROP DATABASE b42897_db2; +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; +use test; +CREATE TABLE t1 (`key` TEXT, `text` TEXT); +LOAD DATA INFILE '../../std_data/loaddata2.dat' REPLACE INTO TABLE `t1` FIELDS TERMINATED BY ','; +SELECT * FROM t1; +key text +Field A 'Field B' +Field 1 'Field 2' +Field 3 'Field 4' +'Field 5' 'Field 6' +Field 6 'Field 7' +DROP TABLE t1; diff --git a/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result b/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result index 35696615b5a..ba0aa847cf7 100644 --- a/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result +++ b/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result @@ -53,7 +53,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 556 +Read_Master_Log_Pos 560 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 diff --git a/mysql-test/suite/rpl/r/rpl_loaddata_map.result b/mysql-test/suite/rpl/r/rpl_loaddata_map.result index 006f84043a4..91624b15ef8 100644 --- a/mysql-test/suite/rpl/r/rpl_loaddata_map.result +++ b/mysql-test/suite/rpl/r/rpl_loaddata_map.result @@ -20,7 +20,7 @@ master-bin.000001 # Query # # use `test`; create table t2 (id int not null prima master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# master-bin.000001 # Append_block # # ;file_id=#;block_len=# master-bin.000001 # Append_block # # ;file_id=#;block_len=# -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (id) ;file_id=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`id`) ;file_id=# ==== Verify results on slave ==== [on slave] select count(*) from t2 /* 5 000 */; diff --git a/mysql-test/suite/rpl/r/rpl_stm_log.result b/mysql-test/suite/rpl/r/rpl_stm_log.result index d73b8990041..47556a33e97 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_log.result +++ b/mysql-test/suite/rpl/r/rpl_stm_log.result @@ -25,7 +25,7 @@ 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 (word char(20) not null)ENGINE=MyISAM master-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581 -master-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (word) ;file_id=1 +master-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (`word`) ;file_id=1 show binlog events from 106 limit 1; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=MyISAM @@ -193,7 +193,7 @@ master-bin.000001 # Query # # use `test`; insert into t1 values (NULL) master-bin.000001 # Query # # use `test`; drop table t1 master-bin.000001 # Query # # use `test`; create table t1 (word char(20) not null)ENGINE=MyISAM master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (word) ;file_id=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (`word`) ;file_id=# master-bin.000001 # Rotate # # master-bin.000002;pos=4 show binlog events in 'master-bin.000002'; Log_name Pos Event_type Server_id End_log_pos Info @@ -218,7 +218,7 @@ slave-bin.000001 # Query 1 # use `test`; insert into t1 values (NULL) slave-bin.000001 # Query 1 # use `test`; drop table t1 slave-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)ENGINE=MyISAM slave-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581 -slave-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE '../../tmp/SQL_LOAD-2-1-1.data' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (word) ;file_id=1 +slave-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE '../../tmp/SQL_LOAD-2-1-1.data' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (`word`) ;file_id=1 slave-bin.000001 # Query 1 # use `test`; create table t3 (a int)ENGINE=MyISAM slave-bin.000001 # Rotate 2 # slave-bin.000002;pos=4 show binlog events in 'slave-bin.000002' from 4; diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index 78661b1bbc4..687ad62b17c 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -71,7 +71,7 @@ select "--- --position --" as ""; --enable_query_log --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ ---exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --position=330 $MYSQLD_DATADIR/master-bin.000002 +--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --position=332 $MYSQLD_DATADIR/master-bin.000002 # These are tests for remote binlog. @@ -108,7 +108,7 @@ select "--- --position --" as ""; --enable_query_log --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ ---exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --position=330 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 +--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --position=332 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 # Bug#7853 mysqlbinlog does not accept input from stdin --disable_query_log diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 8109ca4313e..326a7517ed6 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -640,7 +640,11 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, if (n++) pfields.append(", "); if (item->name) + { + pfields.append("`"); pfields.append(item->name); + pfields.append("`"); + } else item->print(&pfields, QT_ORDINARY); } @@ -660,7 +664,9 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, val= lv++; if (n++) pfields.append(", "); + pfields.append("`"); pfields.append(item->name); + pfields.append("`"); pfields.append("="); val->print(&pfields, QT_ORDINARY); } From 63ff2b4c2e7db9872515cec3d897817ac83d109c Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Sun, 6 Dec 2009 18:11:37 +0100 Subject: [PATCH 021/157] Bug #47391 no stack trace printed to error log on solaris after a crash This patch adds a Solaris-specific version of print_stacktrace() which uses printstack(2), available on all Solaris versions since Solaris 9. (While Solaris 11 adds support for the glibc functions backtrace_*() as of PSARC/2007/162, printstack() is used for consistency over all Solaris versions.) The symbol names are mangled, so use of c++filt may be required as described in the MySQL documentation. sql/stacktrace.c: Added Solaris-specific print_stacktrace(). --- sql/stacktrace.c | 19 +++++++++++++++++++ sql/stacktrace.h | 3 +++ 2 files changed, 22 insertions(+) diff --git a/sql/stacktrace.c b/sql/stacktrace.c index 4e6ad68c172..295a7a3e1e2 100644 --- a/sql/stacktrace.c +++ b/sql/stacktrace.c @@ -226,6 +226,25 @@ end: stack trace is much more helpful in diagnosing the problem, so please do \n\ resolve it\n"); } + +#elif defined(__sun) + +/* Use Solaris' symbolic stack trace routine. */ +#include + +void print_stacktrace(gptr stack_bottom __attribute__((unused)), + ulong thread_stack __attribute__((unused))) +{ + if (printstack(fileno(stderr)) == -1) + fprintf(stderr, "Error when traversing the stack, stack appears corrupt.\n"); + else + fprintf(stderr, "Please read " + "http://dev.mysql.com/doc/mysql/en/using-stack-trace.html " + "and follow instructions on how to resolve the stack trace. " + "Resolved\nstack trace is much more helpful in diagnosing the " + "problem, so please do \nresolve it\n"); +} + #endif /* TARGET_OS_LINUX */ #endif /* HAVE_STACKTRACE */ diff --git a/sql/stacktrace.h b/sql/stacktrace.h index e5e17cc5b9b..718b545b775 100644 --- a/sql/stacktrace.h +++ b/sql/stacktrace.h @@ -35,6 +35,9 @@ void check_thread_lib(void); #define HAVE_STACKTRACE extern void set_exception_pointers(EXCEPTION_POINTERS *ep); #define init_stacktrace() {} +#elif defined(__sun) +#define HAVE_STACKTRACE +#define init_stacktrace() {} #endif #ifdef HAVE_STACKTRACE From c75712caa81a58164019754a3690ddf434d17f61 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Sun, 6 Dec 2009 23:12:11 +0000 Subject: [PATCH 022/157] BUG#49119: Master crashes when executing 'REVOKE ... ON {PROCEDURE|FUNCTION} FROM ...' The master would hit an assertion when binary log was active. This was due to the fact that the thread's diagnostics area was being cleared before writing to the binlog, independently of mysql_routine_grant returning an error or not. When mysql_routine_grant was to return an error, the return value and the diagnostics area contents would mismatch. Consequently, neither my_ok would be called nor an error would be signaled in the diagnostics area, eventually triggering the assertion in net_end_statement. We fix this by not clearing the diagnostics area at binlogging time. --- mysql-test/suite/rpl/r/rpl_do_grant.result | 73 +++++++++++++++ mysql-test/suite/rpl/t/rpl_do_grant.test | 100 +++++++++++++++++++++ sql/sql_acl.cc | 2 +- 3 files changed, 174 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/rpl/r/rpl_do_grant.result b/mysql-test/suite/rpl/r/rpl_do_grant.result index 0913b1afdbf..65c60acc651 100644 --- a/mysql-test/suite/rpl/r/rpl_do_grant.result +++ b/mysql-test/suite/rpl/r/rpl_do_grant.result @@ -169,4 +169,77 @@ DROP USER 'create_rout_db'@'localhost'; call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396"); USE mtr; call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396"); +######## BUG#49119 ####### +### i) test case from the 'how to repeat section' +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; +CREATE TABLE t1(c1 INT); +CREATE PROCEDURE p1() SELECT * FROM t1 | +REVOKE EXECUTE ON PROCEDURE p1 FROM 'root'@'localhost'; +ERROR 42000: There is no such grant defined for user 'root' on host 'localhost' on routine 'p1' +DROP TABLE t1; +DROP PROCEDURE p1; +### ii) Test case in which REVOKE partially succeeds +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; +CREATE TABLE t1(c1 INT); +CREATE PROCEDURE p1() SELECT * FROM t1 | +CREATE USER 'user49119'@'localhost'; +GRANT EXECUTE ON PROCEDURE p1 TO 'user49119'@'localhost'; +############################################################## +### Showing grants for both users: root and user49119 (master) +SHOW GRANTS FOR 'user49119'@'localhost'; +Grants for user49119@localhost +GRANT USAGE ON *.* TO 'user49119'@'localhost' +GRANT EXECUTE ON PROCEDURE `test`.`p1` TO 'user49119'@'localhost' +SHOW GRANTS FOR CURRENT_USER; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +############################################################## +############################################################## +### Showing grants for both users: root and user49119 (master) +SHOW GRANTS FOR 'user49119'@'localhost'; +Grants for user49119@localhost +GRANT USAGE ON *.* TO 'user49119'@'localhost' +GRANT EXECUTE ON PROCEDURE `test`.`p1` TO 'user49119'@'localhost' +SHOW GRANTS FOR CURRENT_USER; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +############################################################## +## This statement will make the revoke fail because root has no +## execute grant. However, it will still revoke the grant for +## user49119. +REVOKE EXECUTE ON PROCEDURE p1 FROM 'user49119'@'localhost', 'root'@'localhost'; +ERROR 42000: There is no such grant defined for user 'root' on host 'localhost' on routine 'p1' +############################################################## +### Showing grants for both users: root and user49119 (master) +### after revoke statement failure +SHOW GRANTS FOR 'user49119'@'localhost'; +Grants for user49119@localhost +GRANT USAGE ON *.* TO 'user49119'@'localhost' +SHOW GRANTS FOR CURRENT_USER; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +############################################################## +############################################################# +### Showing grants for both users: root and user49119 (slave) +### after revoke statement failure (should match +SHOW GRANTS FOR 'user49119'@'localhost'; +Grants for user49119@localhost +GRANT USAGE ON *.* TO 'user49119'@'localhost' +SHOW GRANTS FOR CURRENT_USER; +Grants for root@localhost +GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION +############################################################## +DROP TABLE t1; +DROP PROCEDURE p1; +DROP USER 'user49119'@'localhost'; "End of test" diff --git a/mysql-test/suite/rpl/t/rpl_do_grant.test b/mysql-test/suite/rpl/t/rpl_do_grant.test index a13adf28b95..d6a06f43d18 100644 --- a/mysql-test/suite/rpl/t/rpl_do_grant.test +++ b/mysql-test/suite/rpl/t/rpl_do_grant.test @@ -216,4 +216,104 @@ connection slave; USE mtr; call mtr.add_suppression("Slave: Operation DROP USER failed for 'create_rout_db'@'localhost' Error_code: 1396"); +# BUG#49119: Master crashes when executing 'REVOKE ... ON +# {PROCEDURE|FUNCTION} FROM ...' +# +# The tests are divided into two test cases: +# +# i) a test case that mimics the one in the bug report. +# +# - We show that, despite the fact, that a revoke command fails +# when binlogging is active, the master will not hit an +# assertion. +# +# ii) a test case that partially succeeds on the master will also +# partially succeed on the slave. +# +# - The revoke statement that partially succeeds tries to revoke +# an EXECUTE grant for two users, and only one of the user has +# the specific grant. This will cause mysql to drop one of the +# grants and report error for the statement. The slave should +# also drop the grants that the master succeed and the SQL +# thread should not stop on statement failure. + +-- echo ######## BUG#49119 ####### +-- echo ### i) test case from the 'how to repeat section' +-- source include/master-slave-reset.inc +-- connection master + +CREATE TABLE t1(c1 INT); +DELIMITER |; +CREATE PROCEDURE p1() SELECT * FROM t1 | +DELIMITER ;| +-- error ER_NONEXISTING_PROC_GRANT +REVOKE EXECUTE ON PROCEDURE p1 FROM 'root'@'localhost'; + +-- sync_slave_with_master + +-- connection master +DROP TABLE t1; +DROP PROCEDURE p1; + +-- sync_slave_with_master + +-- echo ### ii) Test case in which REVOKE partially succeeds + +-- connection master +-- source include/master-slave-reset.inc +-- connection master + +CREATE TABLE t1(c1 INT); +DELIMITER |; +CREATE PROCEDURE p1() SELECT * FROM t1 | +DELIMITER ;| + +CREATE USER 'user49119'@'localhost'; +GRANT EXECUTE ON PROCEDURE p1 TO 'user49119'@'localhost'; + +-- echo ############################################################## +-- echo ### Showing grants for both users: root and user49119 (master) +SHOW GRANTS FOR 'user49119'@'localhost'; +SHOW GRANTS FOR CURRENT_USER; +-- echo ############################################################## + +-- sync_slave_with_master + +-- echo ############################################################## +-- echo ### Showing grants for both users: root and user49119 (master) +SHOW GRANTS FOR 'user49119'@'localhost'; +SHOW GRANTS FOR CURRENT_USER; +-- echo ############################################################## + +-- connection master + +-- echo ## This statement will make the revoke fail because root has no +-- echo ## execute grant. However, it will still revoke the grant for +-- echo ## user49119. +-- error ER_NONEXISTING_PROC_GRANT +REVOKE EXECUTE ON PROCEDURE p1 FROM 'user49119'@'localhost', 'root'@'localhost'; + +-- echo ############################################################## +-- echo ### Showing grants for both users: root and user49119 (master) +-- echo ### after revoke statement failure +SHOW GRANTS FOR 'user49119'@'localhost'; +SHOW GRANTS FOR CURRENT_USER; +-- echo ############################################################## + +-- sync_slave_with_master + +-- echo ############################################################# +-- echo ### Showing grants for both users: root and user49119 (slave) +-- echo ### after revoke statement failure (should match +SHOW GRANTS FOR 'user49119'@'localhost'; +SHOW GRANTS FOR CURRENT_USER; +-- echo ############################################################## + +-- connection master +DROP TABLE t1; +DROP PROCEDURE p1; +DROP USER 'user49119'@'localhost'; + +-- sync_slave_with_master + --echo "End of test" diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 77c72066429..3b81a85c368 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3378,7 +3378,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, if (write_to_binlog) { - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + write_bin_log(thd, FALSE, thd->query(), thd->query_length()); } rw_unlock(&LOCK_grant); From bd308d1256fa7af7128c24f4a5e2abfb8274437a Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 7 Dec 2009 16:38:56 +0200 Subject: [PATCH 023/157] Bug #42760: Select doesn't return desired results when we have null values Part 2 : There was a special optimization on the ref access method for ORDER BY ... DESC that was set without actually looking on the type of the selected index for ORDER BY. Fixed the SELECT ... ORDER BY .. DESC (it uses a different code path compared to the ASC that has been fixed with the previous fix). --- mysql-test/r/order_by.result | 9 +++++++++ mysql-test/t/order_by.test | 9 +++++++++ sql/sql_select.cc | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index f0e5b5fde3d..87b6c3f5455 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -1111,5 +1111,14 @@ id select_type table type possible_keys key key_len ref rows Extra SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c; col 1 +# Must use ref-or-null on the a_c index +EXPLAIN +SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c DESC; +id select_type table type possible_keys key key_len ref rows Extra +x x x ref_or_null a_c,a x x x x x +# Must return 1 row +SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c DESC; +col +1 DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index d9a6c0f844d..4da279cc8fd 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -778,6 +778,15 @@ SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c; --echo # Must return 1 row SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c; +# part 2 of the problem : DESC test cases +--echo # Must use ref-or-null on the a_c index +--replace_column 1 x 2 x 3 x 6 x 7 x 8 x 9 x 10 x +EXPLAIN +SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c DESC; +--echo # Must return 1 row +SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c DESC; + + DROP TABLE t1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 9f0843fe0db..f655db0fc32 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12824,7 +12824,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, } DBUG_RETURN(1); } - if (tab->ref.key_parts <= used_key_parts) + if (tab->ref.key_parts <= used_key_parts && tab->type == JT_REF) { /* SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC From 91aa5e248ed2897a7cad0e3060ce1689fee6a5b2 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 Dec 2009 16:35:00 +0100 Subject: [PATCH 024/157] Raise version number after cloning 5.0.89 --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index e14b4014bea..b206dfbd079 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.89) +AM_INIT_AUTOMAKE(mysql, 5.0.90) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 @@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=89 +NDB_VERSION_BUILD=90 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? From d83167f3ca8ca74197e45f29bd29ceaeebedc2d7 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Tue, 8 Dec 2009 16:03:19 +0000 Subject: [PATCH 025/157] Post-push fix for BUG#45292. Disabled execution in valgrind to avoid false positive memory leaks due to fault-injection tests (i.e. call to abort()). --- mysql-test/suite/binlog/t/binlog_index.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/suite/binlog/t/binlog_index.test b/mysql-test/suite/binlog/t/binlog_index.test index 6bfa625422c..9d4a49602a6 100644 --- a/mysql-test/suite/binlog/t/binlog_index.test +++ b/mysql-test/suite/binlog/t/binlog_index.test @@ -3,6 +3,8 @@ # source include/have_log_bin.inc; source include/not_embedded.inc; +# Don't test this under valgrind, memory leaks will occur +--source include/not_valgrind.inc source include/have_debug.inc; call mtr.add_suppression('Attempting backtrace'); call mtr.add_suppression('MSYQL_BIN_LOG::purge_logs failed to process registered files that would be purged.'); From bc2b3d2ccc109768cf918d91e08639b530518ea1 Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Wed, 9 Dec 2009 14:13:56 +0800 Subject: [PATCH 026/157] BUG#45520 rpl_killed_ddl fails sporadically in pb2 There are three issues that caused rpl_killed_ddl fails sporadically in pb2: 1) thd->clear_error() was not called before create Query event if operation is executed successfully. 2) DATABASE d2 might do exist because the statement to CREATE or ALTER it was killed 3) because of bug 43353, kill the query that do DROP FUNCTION or DROP PROCEDURE can result in SP not found This patch fixed all above issues by: 1) Called thd->clear_error() if the operation succeeded. 2) Add IF EXISTS to the DROP DATABASE d2 statement 3) Temporarily disabled testing DROP FUNCTION/PROCEDURE IF EXISTS. mysql-test/t/rpl_killed_ddl.test: DATABASE d2 might not exists, add IF EXITS to the DROP statement sql/sql_db.cc: Called thd->clear_error() if the operation succeeded --- mysql-test/r/rpl_killed_ddl.result | 12 +++--------- mysql-test/t/rpl_killed_ddl.test | 23 ++++++++++++++++------- sql/sql_db.cc | 5 +++-- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/rpl_killed_ddl.result b/mysql-test/r/rpl_killed_ddl.result index aa419a8556e..b9ee915bdce 100644 --- a/mysql-test/r/rpl_killed_ddl.result +++ b/mysql-test/r/rpl_killed_ddl.result @@ -53,7 +53,7 @@ source include/diff_master_slave.inc; DROP DATABASE d1; source include/kill_query.inc; source include/diff_master_slave.inc; -DROP DATABASE d2; +DROP DATABASE IF EXISTS d2; source include/kill_query.inc; source include/diff_master_slave.inc; CREATE FUNCTION f2 () RETURNS INT DETERMINISTIC @@ -63,10 +63,7 @@ source include/diff_master_slave.inc; ALTER FUNCTION f1 SQL SECURITY INVOKER; source include/kill_query.inc; source include/diff_master_slave.inc; -DROP FUNCTION IF EXISTS f1; -source include/kill_query.inc; -source include/diff_master_slave.inc; -DROP FUNCTION IF EXISTS f2; +DROP FUNCTION f1; source include/kill_query.inc; source include/diff_master_slave.inc; CREATE PROCEDURE p2 (OUT rows INT) @@ -79,10 +76,7 @@ source include/diff_master_slave.inc; ALTER PROCEDURE p1 SQL SECURITY INVOKER COMMENT 'return rows of table t1'; source include/kill_query.inc; source include/diff_master_slave.inc; -DROP PROCEDURE IF EXISTS p1; -source include/kill_query.inc; -source include/diff_master_slave.inc; -DROP PROCEDURE IF EXISTS p2; +DROP PROCEDURE p1; source include/kill_query.inc; source include/diff_master_slave.inc; CREATE TABLE t2 (b int); diff --git a/mysql-test/t/rpl_killed_ddl.test b/mysql-test/t/rpl_killed_ddl.test index f4f2f6ac320..7c07d5eecf0 100644 --- a/mysql-test/t/rpl_killed_ddl.test +++ b/mysql-test/t/rpl_killed_ddl.test @@ -123,7 +123,7 @@ source include/kill_query_and_diff_master_slave.inc; send DROP DATABASE d1; source include/kill_query_and_diff_master_slave.inc; -send DROP DATABASE d2; +send DROP DATABASE IF EXISTS d2; source include/kill_query_and_diff_master_slave.inc; ######## FUNCTION ######## @@ -139,13 +139,21 @@ source include/kill_query_and_diff_master_slave.inc; # function f1 probably does not exist because the ALTER query was # killed -send DROP FUNCTION IF EXISTS f1; +send DROP FUNCTION f1; source include/kill_query_and_diff_master_slave.inc; # function f2 probably does not exist because the CREATE query was # killed -send DROP FUNCTION IF EXISTS f2; -source include/kill_query_and_diff_master_slave.inc; +# +# Temporarily disabled. Because of BUG#43353, KILL the query may +# result in function not found, and for 5.1, DROP statements will be +# logged if the function is not found on master, so the following DROP +# FUNCTION statement may be interrupted and not drop the function on +# master, but still get logged and executed on slave and cause +# inconsistence. Also disable the following DROP PROCEDURE IF EXITS +# below. +#send DROP FUNCTION IF EXISTS f2; +#source include/kill_query_and_diff_master_slave.inc; ######## PROCEDURE ######## @@ -163,11 +171,12 @@ source include/kill_query_and_diff_master_slave.inc; send ALTER PROCEDURE p1 SQL SECURITY INVOKER COMMENT 'return rows of table t1'; source include/kill_query_and_diff_master_slave.inc; -send DROP PROCEDURE IF EXISTS p1; +send DROP PROCEDURE p1; source include/kill_query_and_diff_master_slave.inc; -send DROP PROCEDURE IF EXISTS p2; -source include/kill_query_and_diff_master_slave.inc; +# Temporarily disabled because of bug#43353, see comment above for DROP FUNCTION IF EXISTS +#send DROP PROCEDURE IF EXISTS p2; +#source include/kill_query_and_diff_master_slave.inc; ######## TABLE ######## diff --git a/sql/sql_db.cc b/sql/sql_db.cc index be538783458..2ad3953625f 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -541,6 +541,7 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, file. In this case it's best to just continue as if nothing has happened. (This is a very unlikely senario) */ + thd->clear_error(); } if (!silent) @@ -644,6 +645,7 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) if (mysql_bin_log.is_open()) { + thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, 0, /* suppress_use */ TRUE, THD::NOT_KILLED); @@ -655,7 +657,6 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) qinfo.db = db; qinfo.db_len = (uint) strlen(db); - thd->clear_error(); /* These DDL methods and logging protected with LOCK_mysql_create_db */ mysql_bin_log.write(&qinfo); } @@ -769,6 +770,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) } if (mysql_bin_log.is_open()) { + thd->clear_error(); Query_log_event qinfo(thd, query, query_length, 0, /* suppress_use */ TRUE, THD::NOT_KILLED); /* @@ -779,7 +781,6 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) qinfo.db = db; qinfo.db_len = (uint) strlen(db); - thd->clear_error(); /* These DDL methods and logging protected with LOCK_mysql_create_db */ mysql_bin_log.write(&qinfo); } From b3d9f784783482486fa59a2d93da27aede238154 Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Wed, 9 Dec 2009 14:27:46 +0800 Subject: [PATCH 027/157] removed rpl_killed_ddl from disabled list --- mysql-test/t/disabled.def | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 7ce67d3fa89..062667c249e 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -25,4 +25,3 @@ loaddata_autocom_ndb : Bug#35148: Error '4009 Cluster Failure' in various tests ndb_autodiscover3 : Bug#35148: Error '4009 Cluster Failure' in various tests on various platforms ndb_autodiscover : Bug#45972: ndb.ndb_autodiscover fails occasionally with pb2 ndb_autodiscover2 : Bug#45972: ndb.ndb_autodiscover fails occasionally with pb2 -rpl_killed_ddl : Bug#45520: rpl_killed_ddl fails sporadically in pb2 From 9060aa68afa8483883583b3b25e748f17ca6d3a5 Mon Sep 17 00:00:00 2001 From: Olav Sandstaa Date: Wed, 9 Dec 2009 10:16:11 +0100 Subject: [PATCH 028/157] Fix for Bug#49506 Valgrind error in make_cond_for_table_from_pred This fix has been proposed by Sergey Petrunya and has been contributed under SCA by sca@askmonty.org. The cause for this valgrind error is that in the function add_cond_and_fix() in sql_select.cc an Item_cond_and object is created. This is marked as fixed but does not have a correct table_map() attribute. Later, in make_join_select(), if engine_condition_pushdown is in use, this table map is used and results in the valgrind error. The fix is to add a call to update_used_tables() in add_cond_and_fix() so that the table map is updated correctly. This patch is tested by multiple existing tests (e.g. the tests innodb_mysql, innodb, fulltext, compress all produces this valgrind warning/error without this fix). sql/sql_select.cc: In add_cond_and_fix() add a call to update_used_tables() to ensure the table map is updated. --- sql/sql_select.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 569d8183ab6..b2a4958020a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5859,6 +5859,7 @@ inline void add_cond_and_fix(Item **e1, Item *e2) { *e1= res; res->quick_fix_field(); + res->update_used_tables(); } } else From 1285ecd4688295c0aae28b314ef8a4c9ae3b6c14 Mon Sep 17 00:00:00 2001 From: Evgeny Potemkin Date: Wed, 9 Dec 2009 18:43:45 +0300 Subject: [PATCH 029/157] Bug#49489: Uninitialized cache led to a wrong result. Arg_comparator uses Item_cache objects to store constants being compared when they're need a type conversion. Because this cache wasn't initialized properly Arg_comparator might produce wrong comparison result. The Arg_comparator::cache_converted_constant function now initializes cache prior to usage. mysql-test/r/select.result: Added a test case for he bug#49489. mysql-test/t/select.test: Added a test case for he bug#49489. sql/item_cmpfunc.cc: Bug#49489: Uninitialized cache led to a wrong result. The Arg_comparator::cache_converted_constant function now initializes cache prior to usage. --- mysql-test/r/select.result | 10 ++++++++++ mysql-test/t/select.test | 9 +++++++++ sql/item_cmpfunc.cc | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index d0b2a575a32..1750051289a 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4609,4 +4609,14 @@ HAVING v <= 't' ORDER BY pk; v DROP TABLE t1; +# +# Bug#49489 Uninitialized cache led to a wrong result. +# +CREATE TABLE t1(c1 DOUBLE(5,4)); +INSERT INTO t1 VALUES (9.1234); +SELECT * FROM t1 WHERE c1 < 9.12345; +c1 +9.1234 +DROP TABLE t1; +# End of test for bug#49489. End of 5.1 tests diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index ac65e5cbaf5..982aec726f7 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -3964,4 +3964,13 @@ ORDER BY pk; DROP TABLE t1; +--echo # +--echo # Bug#49489 Uninitialized cache led to a wrong result. +--echo # +CREATE TABLE t1(c1 DOUBLE(5,4)); +INSERT INTO t1 VALUES (9.1234); +SELECT * FROM t1 WHERE c1 < 9.12345; +DROP TABLE t1; +--echo # End of test for bug#49489. + --echo End of 5.1 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 5415d6f4f8a..a3c3051d790 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1023,7 +1023,7 @@ Item** Arg_comparator::cache_converted_constant(THD *thd, Item **value, (*value)->const_item() && type != (*value)->result_type()) { Item_cache *cache= Item_cache::get_cache(*value, type); - cache->store(*value); + cache->setup(*value); *cache_item= cache; return cache_item; } From 91689490478f3d8a2fc6280b57d3a922f5e357f5 Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Thu, 10 Dec 2009 11:44:19 +0800 Subject: [PATCH 030/157] Post fix for bug#45520 mysql-test/include/kill_query.inc: Error 1034 can be generated when change MyISAM table indexes was interrupted mysql-test/r/rpl_killed_ddl.result: table t4 may not exists because the ALTER above was interrupted mysql-test/t/rpl_killed_ddl.test: table t4 may not exists because the ALTER above was interrupted --- mysql-test/include/kill_query.inc | 2 +- mysql-test/r/rpl_killed_ddl.result | 1 + mysql-test/t/rpl_killed_ddl.test | 5 +++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/mysql-test/include/kill_query.inc b/mysql-test/include/kill_query.inc index 341c3b93535..b303ed0ec39 100644 --- a/mysql-test/include/kill_query.inc +++ b/mysql-test/include/kill_query.inc @@ -52,7 +52,7 @@ if (`SELECT '$debug_lock' != ''`) # reap the result of the waiting query connection $connection_name; -error 0, 1317, 1307, 1306, 1334, 1305; +error 0, 1317, 1307, 1306, 1334, 1305, 1034; reap; connection master; diff --git a/mysql-test/r/rpl_killed_ddl.result b/mysql-test/r/rpl_killed_ddl.result index b9ee915bdce..59c80d8f6cc 100644 --- a/mysql-test/r/rpl_killed_ddl.result +++ b/mysql-test/r/rpl_killed_ddl.result @@ -94,6 +94,7 @@ source include/diff_master_slave.inc; DROP INDEX i1 on t1; source include/kill_query.inc; source include/diff_master_slave.inc; +CREATE TABLE IF NOT EXISTS t4 (a int); CREATE TRIGGER tr2 BEFORE INSERT ON t4 FOR EACH ROW BEGIN DELETE FROM t1 WHERE a=NEW.a; diff --git a/mysql-test/t/rpl_killed_ddl.test b/mysql-test/t/rpl_killed_ddl.test index 7c07d5eecf0..b0d7258998f 100644 --- a/mysql-test/t/rpl_killed_ddl.test +++ b/mysql-test/t/rpl_killed_ddl.test @@ -203,6 +203,11 @@ source include/kill_query_and_diff_master_slave.inc; ######## TRIGGER ######## +# Make sure table t4 exists +connection master; +CREATE TABLE IF NOT EXISTS t4 (a int); +connection master1; + let $diff_statement= SHOW TRIGGERS LIKE 'v%'; DELIMITER //; From 3246383301e2eacfd14bdb0f5399ab44659002fe Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Thu, 10 Dec 2009 10:05:44 +0400 Subject: [PATCH 031/157] Bug #49480: WHERE using YEAR columns returns unexpected results A few problems were found in the fix for bug 43668: 1) Comparison of the YEAR column with NULL always returned TRUE; 2) Comparison of the YEAR column with constants always returned unpredictable result; 3) Unnecessary conversion warnings when comparing a non-integer constant with a NULL value in the YEAR column; The problems described above have been resolved with an exception: zero (i.e. invalid) YEAR column value comparison with 00 or 2000 still fail (it is not a regression and it was not a regression), so MIN/MAX on YEAR column containing zero value still fail. mysql-test/r/type_year.result: Test case for bug #49480. mysql-test/t/type_year.test: Test case for bug #49480. sql/item_cmpfunc.cc: - The get_year_value() function has been modified to make its return value compatible with the get_datetime_value() return value (i.e. to convert numeric values into the YYYY0000000000 (YYYY-00-00 00:00:00) form. - The Arg_comparator::set_cmp_func method has been modified to use the get_year_value function if get_datetime_value() is not applicable. From now only 2 cases have a special processing there: * both comparing items have MYSQL_TYPE_YEAR field type or * one item have is MYSQL_TYPE_YEAR and other one is is_datetime()-compliant. - New helper function try_year_cmp_func() has been added for the better code readability to call from Arg_comparator::set_cmp_func(). - The Arg_comparator::compare_year method has been removed since get_year_value() is compatible with the old Arg_comparator::compare_datetime method that doesn't have problems #1-#3 (see whole patch entry commentary). sql/item_cmpfunc.h: - New helper function try_year_cmp_func() has been added for the better code readability to call from Arg_comparator::set_cmp_func(). - Unnecessary Arg_comparator::year_as_datetime and Arg_comparator::compare_year() declarations have been removed. --- mysql-test/r/type_year.result | 264 ++++++++++++++++++++++++++++++++++ mysql-test/t/type_year.test | 106 ++++++++++++++ sql/item_cmpfunc.cc | 144 +++++++------------ sql/item_cmpfunc.h | 9 +- 4 files changed, 421 insertions(+), 102 deletions(-) diff --git a/mysql-test/r/type_year.result b/mysql-test/r/type_year.result index e52947455c8..56b326327c6 100644 --- a/mysql-test/r/type_year.result +++ b/mysql-test/r/type_year.result @@ -46,3 +46,267 @@ a 2001 drop table t1; End of 5.0 tests +# +# Bug #49480: WHERE using YEAR columns returns unexpected results +# +CREATE TABLE t2(yy YEAR(2), c2 CHAR(4)); +CREATE TABLE t4(yyyy YEAR(4), c4 CHAR(4)); +INSERT INTO t2 (c2) VALUES (NULL),(1970),(1999),(2000),(2001),(2069); +INSERT INTO t4 (c4) SELECT c2 FROM t2; +UPDATE t2 SET yy = c2; +UPDATE t4 SET yyyy = c4; +SELECT * FROM t2; +yy c2 +NULL NULL +70 1970 +99 1999 +00 2000 +01 2001 +69 2069 +SELECT * FROM t4; +yyyy c4 +NULL NULL +1970 1970 +1999 1999 +2000 2000 +2001 2001 +2069 2069 +# Comparison of YEAR(2) with YEAR(4) +SELECT * FROM t2, t4 WHERE yy = yyyy; +yy c2 yyyy c4 +70 1970 1970 1970 +99 1999 1999 1999 +00 2000 2000 2000 +01 2001 2001 2001 +69 2069 2069 2069 +SELECT * FROM t2, t4 WHERE yy <=> yyyy; +yy c2 yyyy c4 +NULL NULL NULL NULL +70 1970 1970 1970 +99 1999 1999 1999 +00 2000 2000 2000 +01 2001 2001 2001 +69 2069 2069 2069 +SELECT * FROM t2, t4 WHERE yy < yyyy; +yy c2 yyyy c4 +70 1970 1999 1999 +70 1970 2000 2000 +99 1999 2000 2000 +70 1970 2001 2001 +99 1999 2001 2001 +00 2000 2001 2001 +70 1970 2069 2069 +99 1999 2069 2069 +00 2000 2069 2069 +01 2001 2069 2069 +SELECT * FROM t2, t4 WHERE yy > yyyy; +yy c2 yyyy c4 +99 1999 1970 1970 +00 2000 1970 1970 +01 2001 1970 1970 +69 2069 1970 1970 +00 2000 1999 1999 +01 2001 1999 1999 +69 2069 1999 1999 +01 2001 2000 2000 +69 2069 2000 2000 +69 2069 2001 2001 +# Comparison of YEAR(2) with YEAR(2) +SELECT * FROM t2 a, t2 b WHERE a.yy = b.yy; +yy c2 yy c2 +70 1970 70 1970 +99 1999 99 1999 +00 2000 00 2000 +01 2001 01 2001 +69 2069 69 2069 +SELECT * FROM t2 a, t2 b WHERE a.yy <=> b.yy; +yy c2 yy c2 +NULL NULL NULL NULL +70 1970 70 1970 +99 1999 99 1999 +00 2000 00 2000 +01 2001 01 2001 +69 2069 69 2069 +SELECT * FROM t2 a, t2 b WHERE a.yy < b.yy; +yy c2 yy c2 +70 1970 99 1999 +70 1970 00 2000 +99 1999 00 2000 +70 1970 01 2001 +99 1999 01 2001 +00 2000 01 2001 +70 1970 69 2069 +99 1999 69 2069 +00 2000 69 2069 +01 2001 69 2069 +# Comparison of YEAR(4) with YEAR(4) +SELECT * FROM t4 a, t4 b WHERE a.yyyy = b.yyyy; +yyyy c4 yyyy c4 +1970 1970 1970 1970 +1999 1999 1999 1999 +2000 2000 2000 2000 +2001 2001 2001 2001 +2069 2069 2069 2069 +SELECT * FROM t4 a, t4 b WHERE a.yyyy <=> b.yyyy; +yyyy c4 yyyy c4 +NULL NULL NULL NULL +1970 1970 1970 1970 +1999 1999 1999 1999 +2000 2000 2000 2000 +2001 2001 2001 2001 +2069 2069 2069 2069 +SELECT * FROM t4 a, t4 b WHERE a.yyyy < b.yyyy; +yyyy c4 yyyy c4 +1970 1970 1999 1999 +1970 1970 2000 2000 +1999 1999 2000 2000 +1970 1970 2001 2001 +1999 1999 2001 2001 +2000 2000 2001 2001 +1970 1970 2069 2069 +1999 1999 2069 2069 +2000 2000 2069 2069 +2001 2001 2069 2069 +# Comparison with constants: +SELECT * FROM t2 WHERE yy = NULL; +yy c2 +SELECT * FROM t4 WHERE yyyy = NULL; +yyyy c4 +SELECT * FROM t2 WHERE yy <=> NULL; +yy c2 +NULL NULL +SELECT * FROM t4 WHERE yyyy <=> NULL; +yyyy c4 +NULL NULL +SELECT * FROM t2 WHERE yy < NULL; +yy c2 +SELECT * FROM t2 WHERE yy > NULL; +yy c2 +SELECT * FROM t2 WHERE yy = NOW(); +yy c2 +SELECT * FROM t4 WHERE yyyy = NOW(); +yyyy c4 +SELECT * FROM t2 WHERE yy = 99; +yy c2 +99 1999 +SELECT * FROM t2 WHERE 99 = yy; +yy c2 +99 1999 +SELECT * FROM t4 WHERE yyyy = 99; +yyyy c4 +1999 1999 +SELECT * FROM t2 WHERE yy = 'test'; +yy c2 +00 2000 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'test' +SELECT * FROM t4 WHERE yyyy = 'test'; +yyyy c4 +Warnings: +Warning 1292 Truncated incorrect DOUBLE value: 'test' +SELECT * FROM t2 WHERE yy = '1999'; +yy c2 +99 1999 +SELECT * FROM t4 WHERE yyyy = '1999'; +yyyy c4 +1999 1999 +SELECT * FROM t2 WHERE yy = 1999; +yy c2 +99 1999 +SELECT * FROM t4 WHERE yyyy = 1999; +yyyy c4 +1999 1999 +SELECT * FROM t2 WHERE yy = 1999.1; +yy c2 +99 1999 +SELECT * FROM t4 WHERE yyyy = 1999.1; +yyyy c4 +1999 1999 +SELECT * FROM t2 WHERE yy = 1998.9; +yy c2 +99 1999 +SELECT * FROM t4 WHERE yyyy = 1998.9; +yyyy c4 +1999 1999 +# Coverage tests for YEAR with zero/2000 constants: +SELECT * FROM t2 WHERE yy = 0; +yy c2 +00 2000 +SELECT * FROM t2 WHERE yy = '0'; +yy c2 +00 2000 +SELECT * FROM t2 WHERE yy = '0000'; +yy c2 +00 2000 +SELECT * FROM t2 WHERE yy = '2000'; +yy c2 +00 2000 +SELECT * FROM t2 WHERE yy = 2000; +yy c2 +00 2000 +SELECT * FROM t4 WHERE yyyy = 0; +yyyy c4 +SELECT * FROM t4 WHERE yyyy = '0'; +yyyy c4 +2000 2000 +SELECT * FROM t4 WHERE yyyy = '0000'; +yyyy c4 +SELECT * FROM t4 WHERE yyyy = '2000'; +yyyy c4 +2000 2000 +SELECT * FROM t4 WHERE yyyy = 2000; +yyyy c4 +2000 2000 +# Comparison with constants those are out of YEAR range +# (coverage test for backward compatibility) +SELECT COUNT(yy) FROM t2; +COUNT(yy) +5 +SELECT COUNT(yyyy) FROM t4; +COUNT(yyyy) +5 +SELECT COUNT(*) FROM t2 WHERE yy = -1; +COUNT(*) +0 +SELECT COUNT(*) FROM t4 WHERE yyyy > -1; +COUNT(*) +5 +SELECT COUNT(*) FROM t2 WHERE yy > -1000000000000000000; +COUNT(*) +5 +SELECT COUNT(*) FROM t4 WHERE yyyy > -1000000000000000000; +COUNT(*) +5 +SELECT COUNT(*) FROM t2 WHERE yy < 2156; +COUNT(*) +5 +SELECT COUNT(*) FROM t4 WHERE yyyy < 2156; +COUNT(*) +5 +SELECT COUNT(*) FROM t2 WHERE yy < 1000000000000000000; +COUNT(*) +5 +SELECT COUNT(*) FROM t4 WHERE yyyy < 1000000000000000000; +COUNT(*) +5 +SELECT * FROM t2 WHERE yy < 123; +yy c2 +70 1970 +99 1999 +00 2000 +01 2001 +69 2069 +SELECT * FROM t2 WHERE yy > 123; +yy c2 +SELECT * FROM t4 WHERE yyyy < 123; +yyyy c4 +SELECT * FROM t4 WHERE yyyy > 123; +yyyy c4 +1970 1970 +1999 1999 +2000 2000 +2001 2001 +2069 2069 +DROP TABLE t2, t4; +# +End of 5.1 tests diff --git a/mysql-test/t/type_year.test b/mysql-test/t/type_year.test index 0e174a556d6..16fd39a59d8 100644 --- a/mysql-test/t/type_year.test +++ b/mysql-test/t/type_year.test @@ -30,3 +30,109 @@ select * from t1; drop table t1; --echo End of 5.0 tests + +--echo # +--echo # Bug #49480: WHERE using YEAR columns returns unexpected results +--echo # + +CREATE TABLE t2(yy YEAR(2), c2 CHAR(4)); +CREATE TABLE t4(yyyy YEAR(4), c4 CHAR(4)); + +INSERT INTO t2 (c2) VALUES (NULL),(1970),(1999),(2000),(2001),(2069); +INSERT INTO t4 (c4) SELECT c2 FROM t2; +UPDATE t2 SET yy = c2; +UPDATE t4 SET yyyy = c4; + +SELECT * FROM t2; +SELECT * FROM t4; + +--echo # Comparison of YEAR(2) with YEAR(4) + +SELECT * FROM t2, t4 WHERE yy = yyyy; +SELECT * FROM t2, t4 WHERE yy <=> yyyy; +SELECT * FROM t2, t4 WHERE yy < yyyy; +SELECT * FROM t2, t4 WHERE yy > yyyy; + +--echo # Comparison of YEAR(2) with YEAR(2) + +SELECT * FROM t2 a, t2 b WHERE a.yy = b.yy; +SELECT * FROM t2 a, t2 b WHERE a.yy <=> b.yy; +SELECT * FROM t2 a, t2 b WHERE a.yy < b.yy; + +--echo # Comparison of YEAR(4) with YEAR(4) + +SELECT * FROM t4 a, t4 b WHERE a.yyyy = b.yyyy; +SELECT * FROM t4 a, t4 b WHERE a.yyyy <=> b.yyyy; +SELECT * FROM t4 a, t4 b WHERE a.yyyy < b.yyyy; + +--echo # Comparison with constants: + +SELECT * FROM t2 WHERE yy = NULL; +SELECT * FROM t4 WHERE yyyy = NULL; +SELECT * FROM t2 WHERE yy <=> NULL; +SELECT * FROM t4 WHERE yyyy <=> NULL; +SELECT * FROM t2 WHERE yy < NULL; +SELECT * FROM t2 WHERE yy > NULL; + +SELECT * FROM t2 WHERE yy = NOW(); +SELECT * FROM t4 WHERE yyyy = NOW(); + +SELECT * FROM t2 WHERE yy = 99; +SELECT * FROM t2 WHERE 99 = yy; +SELECT * FROM t4 WHERE yyyy = 99; + +SELECT * FROM t2 WHERE yy = 'test'; +SELECT * FROM t4 WHERE yyyy = 'test'; + +SELECT * FROM t2 WHERE yy = '1999'; +SELECT * FROM t4 WHERE yyyy = '1999'; + +SELECT * FROM t2 WHERE yy = 1999; +SELECT * FROM t4 WHERE yyyy = 1999; + +SELECT * FROM t2 WHERE yy = 1999.1; +SELECT * FROM t4 WHERE yyyy = 1999.1; + +SELECT * FROM t2 WHERE yy = 1998.9; +SELECT * FROM t4 WHERE yyyy = 1998.9; + +--echo # Coverage tests for YEAR with zero/2000 constants: + +SELECT * FROM t2 WHERE yy = 0; +SELECT * FROM t2 WHERE yy = '0'; +SELECT * FROM t2 WHERE yy = '0000'; +SELECT * FROM t2 WHERE yy = '2000'; +SELECT * FROM t2 WHERE yy = 2000; + +SELECT * FROM t4 WHERE yyyy = 0; +SELECT * FROM t4 WHERE yyyy = '0'; +SELECT * FROM t4 WHERE yyyy = '0000'; +SELECT * FROM t4 WHERE yyyy = '2000'; +SELECT * FROM t4 WHERE yyyy = 2000; + +--echo # Comparison with constants those are out of YEAR range +--echo # (coverage test for backward compatibility) + +SELECT COUNT(yy) FROM t2; +SELECT COUNT(yyyy) FROM t4; + +SELECT COUNT(*) FROM t2 WHERE yy = -1; +SELECT COUNT(*) FROM t4 WHERE yyyy > -1; +SELECT COUNT(*) FROM t2 WHERE yy > -1000000000000000000; +SELECT COUNT(*) FROM t4 WHERE yyyy > -1000000000000000000; + +SELECT COUNT(*) FROM t2 WHERE yy < 2156; +SELECT COUNT(*) FROM t4 WHERE yyyy < 2156; +SELECT COUNT(*) FROM t2 WHERE yy < 1000000000000000000; +SELECT COUNT(*) FROM t4 WHERE yyyy < 1000000000000000000; + +SELECT * FROM t2 WHERE yy < 123; +SELECT * FROM t2 WHERE yy > 123; +SELECT * FROM t4 WHERE yyyy < 123; +SELECT * FROM t4 WHERE yyyy > 123; + +DROP TABLE t2, t4; + +--echo # + +--echo End of 5.1 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 5415d6f4f8a..ed31c19e676 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -956,40 +956,9 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg, if (agg_item_set_converter(coll, owner->func_name(), b, 1, MY_COLL_CMP_CONV, 1)) return 1; - } else if (type != ROW_RESULT && ((*a)->field_type() == MYSQL_TYPE_YEAR || - (*b)->field_type() == MYSQL_TYPE_YEAR)) - { - is_nulls_eq= is_owner_equal_func(); - year_as_datetime= FALSE; - - if ((*a)->is_datetime()) - { - year_as_datetime= TRUE; - get_value_a_func= &get_datetime_value; - } else if ((*a)->field_type() == MYSQL_TYPE_YEAR) - get_value_a_func= &get_year_value; - else - { - /* - Because convert_constant_item is called only for EXECUTE in PS mode - the value of get_value_x_func set in PREPARE might be not - valid for EXECUTE. - */ - get_value_a_func= NULL; - } - - if ((*b)->is_datetime()) - { - year_as_datetime= TRUE; - get_value_b_func= &get_datetime_value; - } else if ((*b)->field_type() == MYSQL_TYPE_YEAR) - get_value_b_func= &get_year_value; - else - get_value_b_func= NULL; - - func= &Arg_comparator::compare_year; - return 0; } + else if (try_year_cmp_func(type)) + return 0; a= cache_converted_constant(thd, a, &a_cache, type); b= cache_converted_constant(thd, b, &b_cache, type); @@ -997,6 +966,45 @@ int Arg_comparator::set_cmp_func(Item_result_field *owner_arg, } +/* + Helper function to call from Arg_comparator::set_cmp_func() +*/ + +bool Arg_comparator::try_year_cmp_func(Item_result type) +{ + if (type == ROW_RESULT) + return FALSE; + + bool a_is_year= (*a)->field_type() == MYSQL_TYPE_YEAR; + bool b_is_year= (*b)->field_type() == MYSQL_TYPE_YEAR; + + if (!a_is_year && !b_is_year) + return FALSE; + + if (a_is_year && b_is_year) + { + get_value_a_func= &get_year_value; + get_value_b_func= &get_year_value; + } + else if (a_is_year && (*b)->is_datetime()) + { + get_value_a_func= &get_year_value; + get_value_b_func= &get_datetime_value; + } + else if (b_is_year && (*a)->is_datetime()) + { + get_value_b_func= &get_year_value; + get_value_a_func= &get_datetime_value; + } + else + return FALSE; + + is_nulls_eq= is_owner_equal_func(); + func= &Arg_comparator::compare_datetime; + + return TRUE; +} + /** Convert and cache a constant. @@ -1147,7 +1155,7 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, /* - Retrieves YEAR value of 19XX form from given item. + Retrieves YEAR value of 19XX-00-00 00:00:00 form from given item. SYNOPSIS get_year_value() @@ -1159,7 +1167,9 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, DESCRIPTION Retrieves the YEAR value of 19XX form from given item for comparison by the - compare_year() function. + compare_datetime() function. + Converts year to DATETIME of form YYYY-00-00 00:00:00 for the compatibility + with the get_datetime_value function result. RETURN obtained value @@ -1186,6 +1196,9 @@ get_year_value(THD *thd, Item ***item_arg, Item **cache_arg, if (value <= 1900) value+= 1900; + /* Convert year to DATETIME of form YYYY-00-00 00:00:00 (YYYY0000000000). */ + value*= 10000000000LL; + return value; } @@ -1615,67 +1628,6 @@ int Arg_comparator::compare_e_row() } -/** - Compare values as YEAR. - - @details - Compare items as YEAR for EQUAL_FUNC and for other comparison functions. - The YEAR values of form 19XX are obtained with help of the get_year_value() - function. - If one of arguments is of DATE/DATETIME type its value is obtained - with help of the get_datetime_value function. In this case YEAR values - prior to comparison are converted to the ulonglong YYYY-00-00 00:00:00 - DATETIME form. - If an argument type neither YEAR nor DATE/DATEIME then val_int function - is used to obtain value for comparison. - - RETURN - If is_nulls_eq is TRUE: - 1 if items are equal or both are null - 0 otherwise - If is_nulls_eq is FALSE: - -1 a < b - 0 a == b or at least one of items is null - 1 a > b - See the table: - is_nulls_eq | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | - a_is_null | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | - b_is_null | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | - result | 1 | 0 | 0 |0/1| 0 | 0 | 0 |-1/0/1| -*/ - -int Arg_comparator::compare_year() -{ - bool a_is_null, b_is_null; - ulonglong val1= get_value_a_func ? - (*get_value_a_func)(thd, &a, &a_cache, *b, &a_is_null) : - (*a)->val_int(); - ulonglong val2= get_value_b_func ? - (*get_value_b_func)(thd, &b, &b_cache, *a, &b_is_null) : - (*b)->val_int(); - if (!(*a)->null_value) - { - if (!(*b)->null_value) - { - if (set_null) - owner->null_value= 0; - /* Convert year to DATETIME of form YYYY-00-00 00:00:00 when necessary. */ - if((*a)->field_type() == MYSQL_TYPE_YEAR && year_as_datetime) - val1*= 10000000000LL; - if((*b)->field_type() == MYSQL_TYPE_YEAR && year_as_datetime) - val2*= 10000000000LL; - - if (val1 < val2) return is_nulls_eq ? 0 : -1; - if (val1 == val2) return is_nulls_eq ? 1 : 0; - return is_nulls_eq ? 0 : 1; - } - } - if (set_null) - owner->null_value= is_nulls_eq ? 0 : 1; - return (is_nulls_eq && (*a)->null_value == (*b)->null_value) ? 1 : 0; -} - - void Item_func_truth::fix_length_and_dec() { maybe_null= 0; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 52af6a31c0c..d4542dac820 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -42,24 +42,22 @@ class Arg_comparator: public Sql_alloc bool is_nulls_eq; // TRUE <=> compare for the EQUAL_FUNC bool set_null; // TRUE <=> set owner->null_value // when one of arguments is NULL. - bool year_as_datetime; // TRUE <=> convert YEAR value to - // the YYYY-00-00 00:00:00 DATETIME - // format. See compare_year. enum enum_date_cmp_type { CMP_DATE_DFLT= 0, CMP_DATE_WITH_DATE, CMP_DATE_WITH_STR, CMP_STR_WITH_DATE }; longlong (*get_value_a_func)(THD *thd, Item ***item_arg, Item **cache_arg, Item *warn_item, bool *is_null); longlong (*get_value_b_func)(THD *thd, Item ***item_arg, Item **cache_arg, Item *warn_item, bool *is_null); + bool try_year_cmp_func(Item_result type); public: DTCollation cmp_collation; /* Allow owner function to use string buffers. */ String value1, value2; Arg_comparator(): thd(0), a_cache(0), b_cache(0), set_null(0), - year_as_datetime(0), get_value_a_func(0), get_value_b_func(0) {}; + get_value_a_func(0), get_value_b_func(0) {}; Arg_comparator(Item **a1, Item **a2): a(a1), b(a2), thd(0), - a_cache(0), b_cache(0), set_null(0), year_as_datetime(0), + a_cache(0), b_cache(0), set_null(0), get_value_a_func(0), get_value_b_func(0) {}; int set_compare_func(Item_result_field *owner, Item_result type); @@ -101,7 +99,6 @@ public: int compare_real_fixed(); int compare_e_real_fixed(); int compare_datetime(); // compare args[0] & args[1] as DATETIMEs - int compare_year(); static enum enum_date_cmp_type can_compare_as_dates(Item *a, Item *b, ulonglong *const_val_arg); From 30e51fe8540026f00c2c599098257c1e33c9b94f Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 10 Dec 2009 11:28:38 +0200 Subject: [PATCH 032/157] Bug #49250 : spatial btree index corruption and crash SPATIAL and FULLTEXT indexes don't support algorithm selection. Disabled by creating a special grammar rule for these in the parser. Added some encasulation of duplicate parser code. --- mysql-test/r/fulltext.result | 14 +++++ mysql-test/r/gis.result | 13 +++++ mysql-test/t/fulltext.test | 17 ++++++ mysql-test/t/gis.test | 15 +++++ sql/sql_yacc.yy | 110 +++++++++++++++++++++-------------- 5 files changed, 126 insertions(+), 43 deletions(-) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index b0197e0aec2..c27915811d6 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -518,3 +518,17 @@ EXECUTE s; MATCH (col) AGAINST('findme') DEALLOCATE PREPARE s; DROP TABLE t1; +# +# Bug #49250 : spatial btree index corruption and crash +# Part two : fulltext syntax check +# +CREATE TABLE t1(col1 TEXT, +FULLTEXT INDEX USING BTREE (col1)); +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 'USING BTREE (col1))' at line 2 +CREATE TABLE t2(col1 TEXT); +CREATE FULLTEXT INDEX USING BTREE ON t2(col); +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 'USING BTREE ON t2(col)' at line 1 +ALTER TABLE t2 ADD FULLTEXT INDEX USING BTREE (col1); +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 'USING BTREE (col1)' at line 1 +DROP TABLE t2; +End of 5.0 tests diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 140c133d75f..158fdb69c10 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -983,4 +983,17 @@ GEOMFROMTEXT( SELECT 1 FROM t1 WHERE a <> (SELECT GEOMETRYCOLLECTIONFROMWKB(b) FROM t1); 1 DROP TABLE t1; +# +# Bug #49250 : spatial btree index corruption and crash +# Part one : spatial syntax check +# +CREATE TABLE t1(col1 MULTIPOLYGON NOT NULL, +SPATIAL INDEX USING BTREE (col1)); +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 'USING BTREE (col1))' at line 2 +CREATE TABLE t2(col1 MULTIPOLYGON NOT NULL); +CREATE SPATIAL INDEX USING BTREE ON t2(col); +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 'USING BTREE ON t2(col)' at line 1 +ALTER TABLE t2 ADD SPATIAL INDEX USING BTREE (col1); +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 'USING BTREE (col1)' at line 1 +DROP TABLE t2; End of 5.0 tests diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 9551c98f143..bcd27e51f24 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -455,3 +455,20 @@ EXECUTE s; DEALLOCATE PREPARE s; DROP TABLE t1; +--echo # +--echo # Bug #49250 : spatial btree index corruption and crash +--echo # Part two : fulltext syntax check +--echo # + +--error ER_PARSE_ERROR +CREATE TABLE t1(col1 TEXT, + FULLTEXT INDEX USING BTREE (col1)); +CREATE TABLE t2(col1 TEXT); +--error ER_PARSE_ERROR +CREATE FULLTEXT INDEX USING BTREE ON t2(col); +--error ER_PARSE_ERROR +ALTER TABLE t2 ADD FULLTEXT INDEX USING BTREE (col1); + +DROP TABLE t2; + +--echo End of 5.0 tests diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index 701a6cef6be..d2bfe7d90d4 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -669,5 +669,20 @@ SELECT 1 FROM t1 WHERE a <> (SELECT GEOMETRYCOLLECTIONFROMWKB(b) FROM t1); DROP TABLE t1; +--echo # +--echo # Bug #49250 : spatial btree index corruption and crash +--echo # Part one : spatial syntax check +--echo # + +--error ER_PARSE_ERROR +CREATE TABLE t1(col1 MULTIPOLYGON NOT NULL, + SPATIAL INDEX USING BTREE (col1)); +CREATE TABLE t2(col1 MULTIPOLYGON NOT NULL); +--error ER_PARSE_ERROR +CREATE SPATIAL INDEX USING BTREE ON t2(col); +--error ER_PARSE_ERROR +ALTER TABLE t2 ADD SPATIAL INDEX USING BTREE (col1); + +DROP TABLE t2; --echo End of 5.0 tests diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2fc85b4bda7..3cd61605033 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -418,6 +418,34 @@ Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal, DBUG_RETURN(result); } + +static bool add_create_index_prepare (LEX *lex, Table_ident *table) +{ + lex->sql_command= SQLCOM_CREATE_INDEX; + if (!lex->current_select->add_table_to_list(lex->thd, table, NULL, + TL_OPTION_UPDATING)) + return TRUE; + lex->alter_info.reset(); + lex->alter_info.flags= ALTER_ADD_INDEX; + lex->col_list.empty(); + lex->change= NullS; + return FALSE; +} + + +static bool add_create_index (LEX *lex, + Key::Keytype type, const char *name, enum ha_key_alg key_alg, + bool generated= 0) +{ + Key *key= new Key(type, name, key_alg, generated, lex->col_list); + if (key == NULL) + return TRUE; + + lex->alter_info.key_list.push_back(key); + lex->col_list.empty(); + return FALSE; +} + %} %union { int num; @@ -1110,7 +1138,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); option_type opt_var_type opt_var_ident_type %type - key_type opt_unique_or_fulltext constraint_key_type + key_type opt_unique fulltext_or_spatial constraint_key_type + key_type_fulltext_or_spatial %type key_alg opt_btree_or_rtree @@ -1543,27 +1572,25 @@ create: } create2 { Lex->current_select= &Lex->select_lex; } - | CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON table_ident + | CREATE opt_unique INDEX_SYM ident key_alg ON table_ident { - LEX *lex=Lex; - lex->sql_command= SQLCOM_CREATE_INDEX; - if (!lex->current_select->add_table_to_list(lex->thd, $7, NULL, - TL_OPTION_UPDATING)) - MYSQL_YYABORT; - lex->alter_info.reset(); - lex->alter_info.flags= ALTER_ADD_INDEX; - lex->col_list.empty(); - lex->change=NullS; - } - '(' key_list ')' - { - LEX *lex=Lex; - Key *key= new Key($2, $4.str, $5, 0, lex->col_list); - if (key == NULL) + if (add_create_index_prepare (Lex, $7)) + MYSQL_YYABORT; + } + '(' key_list ')' + { + if (add_create_index (Lex, $2, $4.str, $5)) + MYSQL_YYABORT; + } + | CREATE fulltext_or_spatial INDEX_SYM ident ON table_ident + { + if (add_create_index_prepare (Lex, $6)) + MYSQL_YYABORT; + } + '(' key_list ')' + { + if (add_create_index (Lex, $2, $4.str, HA_KEY_ALG_UNDEF)) MYSQL_YYABORT; - - lex->alter_info.key_list.push_back(key); - lex->col_list.empty(); } | CREATE DATABASE opt_if_not_exists ident { @@ -3133,23 +3160,18 @@ column_def: key_def: key_type opt_ident key_alg '(' key_list ')' key_alg { - LEX *lex=Lex; - Key *key= new Key($1, $2, $7 ? $7 : $3, 0, lex->col_list); - if (key == NULL) + if (add_create_index (Lex, $1, $2, $7 ? $7 : $3)) + MYSQL_YYABORT; + } + | key_type_fulltext_or_spatial opt_ident '(' key_list ')' + { + if (add_create_index (Lex, $1, $2, HA_KEY_ALG_UNDEF)) MYSQL_YYABORT; - lex->alter_info.key_list.push_back(key); - - lex->col_list.empty(); /* Alloced by sql_alloc */ } | opt_constraint constraint_key_type opt_ident key_alg '(' key_list ')' key_alg { - LEX *lex=Lex; - const char *key_name= $3 ? $3:$1; - Key *key= new Key($2, key_name, $4, 0, lex->col_list); - if (key == NULL) + if (add_create_index (Lex, $2, $3 ? $3:$1, $4)) MYSQL_YYABORT; - lex->alter_info.key_list.push_back(key); - lex->col_list.empty(); /* Alloced by sql_alloc */ } | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references { @@ -3164,13 +3186,9 @@ key_def: if (key == NULL) MYSQL_YYABORT; lex->alter_info.key_list.push_back(key); - key= new Key(Key::MULTIPLE, key_name, - HA_KEY_ALG_UNDEF, 1, - lex->col_list); - if (key == NULL) + if (add_create_index (lex, Key::MULTIPLE, key_name, + HA_KEY_ALG_UNDEF, 1)) MYSQL_YYABORT; - lex->alter_info.key_list.push_back(key); - lex->col_list.empty(); /* Alloced by sql_alloc */ } | constraint opt_check_constraint { @@ -3630,7 +3648,10 @@ delete_option: key_type: key_or_index { $$= Key::MULTIPLE; } - | FULLTEXT_SYM opt_key_or_index { $$= Key::FULLTEXT; } + ; + +key_type_fulltext_or_spatial: + FULLTEXT_SYM opt_key_or_index { $$= Key::FULLTEXT; } | SPATIAL_SYM opt_key_or_index { #ifdef HAVE_SPATIAL @@ -3660,10 +3681,8 @@ keys_or_index: | INDEX_SYM {} | INDEXES {}; -opt_unique_or_fulltext: - /* empty */ { $$= Key::MULTIPLE; } - | UNIQUE_SYM { $$= Key::UNIQUE; } - | FULLTEXT_SYM { $$= Key::FULLTEXT;} +fulltext_or_spatial: + FULLTEXT_SYM { $$= Key::FULLTEXT;} | SPATIAL_SYM { #ifdef HAVE_SPATIAL @@ -3676,6 +3695,11 @@ opt_unique_or_fulltext: } ; +opt_unique: + /* empty */ { $$= Key::MULTIPLE; } + | UNIQUE_SYM { $$= Key::UNIQUE; } + ; + key_alg: /* empty */ { $$= HA_KEY_ALG_UNDEF; } | USING opt_btree_or_rtree { $$= $2; } From 18d09c0183c022ee19eebb71b8278ef2c5219514 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 11 Dec 2009 09:57:38 +0800 Subject: [PATCH 033/157] Bug #48742 Replication: incorrect help text for --init-slave The help text for --init-slave=name: "Command(s) that are executed when a slave connects to this master". This text indicate that the --init-slave option is set on a master server, and the master server passes the option's argument to slave which connects to it. This is wrong. Actually the --init-slave option just can be set on a slave server, and then the slave server executes the argument each time the SQL thread starts. Correct the help text for --init-slave option as following: "Command(s) that are executed by a slave server each time the SQL thread starts." sql/mysqld.cc: Correct the help text for --init-slave option. --- sql/mysqld.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ce1d562d0ca..b4eb96ab65a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5275,7 +5275,8 @@ Disable with --skip-large-pages.", #endif {"init-rpl-role", OPT_INIT_RPL_ROLE, "Set the replication role.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed when a slave connects to this master", + {"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed by a slave server \ +each time the SQL thread starts.", (gptr*) &opt_init_slave, (gptr*) &opt_init_slave, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"innodb", OPT_INNODB, "Enable InnoDB (if this version of MySQL supports it). \ From e3c1ee24fc0128915a3d09ac82c433ab1ae186ee Mon Sep 17 00:00:00 2001 From: V Narayanan Date: Fri, 11 Dec 2009 12:31:16 +0530 Subject: [PATCH 034/157] Bug#49329 example (and other) engines use wrong collation for open tables hash This fix changes the character set used within the IBMDB2I handler to hash table names to information about open tables. Previously, tables with names that differed only in letter case would hash to the same data structure. This caused incorrect behavior or errors when two such tables were in use simultaneously. mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result: Bug#49329 example (and other) engines use wrong collation for open tables hash Result file for the test case. mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test: Bug#49329 example (and other) engines use wrong collation for open tables hash Test case for the bug fix. storage/ibmdb2i/ha_ibmdb2i.cc: Bug#49329 example (and other) engines use wrong collation for open tables hash change the character set used within the IBMDB2I handler to hash table names to information about open tables. --- mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result | 9 +++++++++ mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test | 10 ++++++++++ storage/ibmdb2i/ha_ibmdb2i.cc | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result create mode 100644 mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test diff --git a/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result new file mode 100644 index 00000000000..d5bfc2579fd --- /dev/null +++ b/mysql-test/suite/ibmdb2i/r/ibmdb2i_bug_49329.result @@ -0,0 +1,9 @@ +create table ABC (i int) engine=ibmdb2i; +insert into ABC values(1); +create table abc (i int) engine=ibmdb2i; +insert into abc values (2); +select * from ABC; +i +1 +drop table ABC; +drop table abc; diff --git a/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test new file mode 100644 index 00000000000..615df284d8f --- /dev/null +++ b/mysql-test/suite/ibmdb2i/t/ibmdb2i_bug_49329.test @@ -0,0 +1,10 @@ +source suite/ibmdb2i/include/have_ibmdb2i.inc; +source include/have_case_sensitive_file_system.inc; + +create table ABC (i int) engine=ibmdb2i; +insert into ABC values(1); +create table abc (i int) engine=ibmdb2i; +insert into abc values (2); +select * from ABC; +drop table ABC; +drop table abc; diff --git a/storage/ibmdb2i/ha_ibmdb2i.cc b/storage/ibmdb2i/ha_ibmdb2i.cc index 0fc2d1e83dc..39096be7848 100644 --- a/storage/ibmdb2i/ha_ibmdb2i.cc +++ b/storage/ibmdb2i/ha_ibmdb2i.cc @@ -284,7 +284,7 @@ static int ibmdb2i_init_func(void *p) was_ILE_inited = false; ibmdb2i_hton= (handlerton *)p; VOID(pthread_mutex_init(&ibmdb2i_mutex,MY_MUTEX_INIT_FAST)); - (void) hash_init(&ibmdb2i_open_tables,system_charset_info,32,0,0, + (void) hash_init(&ibmdb2i_open_tables,table_alias_charset,32,0,0, (hash_get_key) ibmdb2i_get_key,0,0); ibmdb2i_hton->state= SHOW_OPTION_YES; From 3fded1b6c1294c24b6d0985ea1c22ebac5332c47 Mon Sep 17 00:00:00 2001 From: V Narayanan Date: Fri, 11 Dec 2009 12:46:57 +0530 Subject: [PATCH 035/157] Bug#49521 SHOW CREATE TABLE on IBMDB2I tables has incorrect fk constraint format The fix inserts newline and comma characters as appropriate into the constraint reporting code to match the formatting required by SHOW CREATE TABLE. Additionally, a erroneously duplicated copy of check_if_incompatible_data() was removed from db2i_constraints.cc since the correct version is already in ha_ibmdb2i.cc. storage/ibmdb2i/db2i_constraints.cc: Bug#49521 SHOW CREATE TABLE on IBMDB2I tables has incorrect fk constraint format - Insert newline and comma characters into the constraint reporting code to match the formatting required by SHOW CREATE TABLE. - Remove an erroneous copy of check_if_incompatible_data() from db2i_constraints.cc. --- storage/ibmdb2i/db2i_constraints.cc | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/storage/ibmdb2i/db2i_constraints.cc b/storage/ibmdb2i/db2i_constraints.cc index 9a96eda1173..1fde0dd3d14 100644 --- a/storage/ibmdb2i/db2i_constraints.cc +++ b/storage/ibmdb2i/db2i_constraints.cc @@ -329,7 +329,7 @@ char* ha_ibmdb2i::get_foreign_key_create_info(void) /* Process the constraint name. */ - info.strncat(STRING_WITH_LEN(" CONSTRAINT ")); + info.strncat(STRING_WITH_LEN(",\n CONSTRAINT ")); convNameForCreateInfo(thd, info, FKCstDef->CstName.Name, FKCstDef->CstName.Len); @@ -398,7 +398,6 @@ char* ha_ibmdb2i::get_foreign_key_create_info(void) if ((i+1) < cstCnt) { - info.strcat(','); tempPtr = (char*)cstHdr + cstHdr->CstLen; cstHdr = (constraint_hdr_t*)(tempPtr); } @@ -671,28 +670,3 @@ uint ha_ibmdb2i::referenced_by_foreign_key(void) } DBUG_RETURN(count); } - - -bool ha_ibmdb2i::check_if_incompatible_data(HA_CREATE_INFO *info, - uint table_changes) -{ - DBUG_ENTER("ha_ibmdb2i::check_if_incompatible_data"); - uint i; - /* Check that auto_increment value and field definitions were - not changed. */ - if ((info->used_fields & HA_CREATE_USED_AUTO && - info->auto_increment_value != 0) || - table_changes != IS_EQUAL_YES) - DBUG_RETURN(COMPATIBLE_DATA_NO); - /* Check if any fields were renamed. */ - for (i= 0; i < table->s->fields; i++) - { - Field *field= table->field[i]; - if (field->flags & FIELD_IS_RENAMED) - { - DBUG_PRINT("info", ("Field has been renamed, copy table")); - DBUG_RETURN(COMPATIBLE_DATA_NO); - } - } - DBUG_RETURN(COMPATIBLE_DATA_YES); -} From 794e2063471998a545e266c7268efaf2ba470d31 Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Fri, 11 Dec 2009 19:11:49 +0100 Subject: [PATCH 036/157] Define _WIN32_WINNT to the minimum supported Windows version, 0x0500 i.e Windows 2000. Visual Studio 2003 and 2005 require _WIN32_WINNT >= 0x0500 (Win2000) for TryEnterCriticalSection. --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5705a2dfe57..bd597cf29c9 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -146,6 +146,7 @@ IF(MSVC) ENDIF(MSVC) ADD_DEFINITIONS("-D_WINDOWS -D__WIN__ -D_CRT_SECURE_NO_DEPRECATE") +ADD_DEFINITIONS("-D_WIN32_WINNT=0x0500") # This definition is necessary to work around a bug with Intellisense described # here: http://tinyurl.com/2cb428. Syntax highlighting is important for proper From 8969530cffde0c7a466cf3aa8c4b7462d0ace2d2 Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Sat, 12 Dec 2009 19:11:25 +0100 Subject: [PATCH 037/157] Bug #45058 init_available_charsets uses double checked locking As documented in the bug report, the double checked locking pattern has inherent issues, and cannot guarantee correct initialization. This patch replaces the logic in init_available_charsets() with the use of pthread_once(3). A wrapper function, my_pthread_once(), is introduced and is used in lieu of direct calls to init_available_charsets(). Related defines MY_PTHREAD_ONCE_* are also introduced. For the Windows platform, the implementation in lp:sysbench is ported. For single-thread use, a simple define calls the function and sets the pthread_once control variable. Charset initialization is modified to use my_pthread_once(). include/my_no_pthread.h: Dummy my_pthread_once() for single thread use. include/my_pthread.h: Declaration for new function my_pthread_once(). mysys/charset.c: Logic in init_available_charsets() is simplified. Using my_pthread_once() for all calls to this func. mysys/my_winthread.c: Windows implementation of my_pthread_once(). --- include/my_no_pthread.h | 8 +++++ include/my_pthread.h | 10 ++++++ include/my_sys.h | 1 - libmysql/libmysql.c | 1 - mysys/charset.c | 77 +++++++++++++---------------------------- mysys/my_init.c | 1 - mysys/my_winthread.c | 32 +++++++++++++++++ netware/libmysqlmain.c | 4 +-- sql/mysqld.cc | 1 - 9 files changed, 77 insertions(+), 58 deletions(-) diff --git a/include/my_no_pthread.h b/include/my_no_pthread.h index b11dbff42f0..511fac407d5 100644 --- a/include/my_no_pthread.h +++ b/include/my_no_pthread.h @@ -47,4 +47,12 @@ #define rw_unlock(A) #define rwlock_destroy(A) +typedef int my_pthread_once_t; +#define MY_PTHREAD_ONCE_INIT 0 +#define MY_PTHREAD_ONCE_DONE 1 + +#define my_pthread_once(C,F) do { \ + if (*(C) != MY_PTHREAD_ONCE_DONE) { F(); *(C)= MY_PTHREAD_ONCE_DONE; } \ + } while(0) + #endif diff --git a/include/my_pthread.h b/include/my_pthread.h index 151cb34faff..e9256610ea7 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -69,6 +69,11 @@ typedef int pthread_mutexattr_t; #define pthread_handler_t EXTERNC void * __cdecl typedef void * (__cdecl *pthread_handler)(void *); +typedef volatile LONG my_pthread_once_t; +#define MY_PTHREAD_ONCE_INIT 0 +#define MY_PTHREAD_ONCE_INPROGRESS 1 +#define MY_PTHREAD_ONCE_DONE 2 + /* Struct and macros to be used in combination with the windows implementation of pthread_cond_timedwait @@ -114,6 +119,7 @@ int pthread_attr_init(pthread_attr_t *connect_att); int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack); int pthread_attr_setprio(pthread_attr_t *connect_att,int priority); int pthread_attr_destroy(pthread_attr_t *connect_att); +int my_pthread_once(my_pthread_once_t *once_control,void (*init_routine)(void)); struct tm *localtime_r(const time_t *timep,struct tm *tmp); struct tm *gmtime_r(const time_t *timep,struct tm *tmp); @@ -210,6 +216,10 @@ extern int my_pthread_getprio(pthread_t thread_id); #define pthread_handler_t EXTERNC void * typedef void *(* pthread_handler)(void *); +#define my_pthread_once_t pthread_once_t +#define MY_PTHREAD_ONCE_INIT PTHREAD_ONCE_INIT +#define my_pthread_once(C,F) pthread_once(C,F) + /* Test first for RTS or FSU threads */ #if defined(PTHREAD_SCOPE_GLOBAL) && !defined(PTHREAD_SCOPE_SYSTEM) diff --git a/include/my_sys.h b/include/my_sys.h index b4aac3a17bd..a4ff5c30de7 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -951,7 +951,6 @@ extern my_bool resolve_collation(const char *cl_name, CHARSET_INFO *default_cl, CHARSET_INFO **cl); -extern void free_charsets(void); extern char *get_charsets_dir(char *buf); extern my_bool my_charset_same(CHARSET_INFO *cs1, CHARSET_INFO *cs2); extern my_bool init_compiled_charsets(myf flags); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 1264f2765ba..36b1d9cac72 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -211,7 +211,6 @@ void STDCALL mysql_server_end() } else { - free_charsets(); mysql_thread_end(); } diff --git a/mysys/charset.c b/mysys/charset.c index b23ab084e90..d59be4ab6c7 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -321,7 +321,6 @@ static int add_collation(CHARSET_INFO *cs) #define MY_CHARSET_INDEX "Index.xml" const char *charsets_dir= NULL; -static int charset_initialized=0; static my_bool my_read_charset_file(const char *filename, myf myflags) @@ -399,63 +398,37 @@ static void *cs_alloc(size_t size) } -#ifdef __NETWARE__ -my_bool STDCALL init_available_charsets(myf myflags) -#else -static my_bool init_available_charsets(myf myflags) -#endif +static my_pthread_once_t charsets_initialized= MY_PTHREAD_ONCE_INIT; + +static void init_available_charsets(void) { char fname[FN_REFLEN + sizeof(MY_CHARSET_INDEX)]; - my_bool error=FALSE; - /* - We have to use charset_initialized to not lock on THR_LOCK_charset - inside get_internal_charset... - */ - if (!charset_initialized) + CHARSET_INFO **cs; + + bzero(&all_charsets,sizeof(all_charsets)); + init_compiled_charsets(MYF(0)); + + /* Copy compiled charsets */ + for (cs=all_charsets; + cs < all_charsets+array_elements(all_charsets)-1 ; + cs++) { - CHARSET_INFO **cs; - /* - To make things thread safe we are not allowing other threads to interfere - while we may changing the cs_info_table - */ - pthread_mutex_lock(&THR_LOCK_charset); - if (!charset_initialized) + if (*cs) { - bzero(&all_charsets,sizeof(all_charsets)); - init_compiled_charsets(myflags); - - /* Copy compiled charsets */ - for (cs=all_charsets; - cs < all_charsets+array_elements(all_charsets)-1 ; - cs++) - { - if (*cs) - { - if (cs[0]->ctype) - if (init_state_maps(*cs)) - *cs= NULL; - } - } - - strmov(get_charsets_dir(fname), MY_CHARSET_INDEX); - error= my_read_charset_file(fname,myflags); - charset_initialized=1; + if (cs[0]->ctype) + if (init_state_maps(*cs)) + *cs= NULL; } - pthread_mutex_unlock(&THR_LOCK_charset); } - return error; -} - - -void free_charsets(void) -{ - charset_initialized=0; + + strmov(get_charsets_dir(fname), MY_CHARSET_INDEX); + my_read_charset_file(fname, MYF(0)); } uint get_collation_number(const char *name) { - init_available_charsets(MYF(0)); + my_pthread_once(&charsets_initialized, init_available_charsets); return get_collation_number_internal(name); } @@ -463,7 +436,7 @@ uint get_collation_number(const char *name) uint get_charset_number(const char *charset_name, uint cs_flags) { CHARSET_INFO **cs; - init_available_charsets(MYF(0)); + my_pthread_once(&charsets_initialized, init_available_charsets); for (cs= all_charsets; cs < all_charsets+array_elements(all_charsets)-1 ; @@ -480,7 +453,7 @@ uint get_charset_number(const char *charset_name, uint cs_flags) const char *get_charset_name(uint charset_number) { CHARSET_INFO *cs; - init_available_charsets(MYF(0)); + my_pthread_once(&charsets_initialized, init_available_charsets); cs=all_charsets[charset_number]; if (cs && (cs->number == charset_number) && cs->name ) @@ -538,7 +511,7 @@ CHARSET_INFO *get_charset(uint cs_number, myf flags) if (cs_number == default_charset_info->number) return default_charset_info; - (void) init_available_charsets(MYF(0)); /* If it isn't initialized */ + my_pthread_once(&charsets_initialized, init_available_charsets); if (!cs_number || cs_number >= array_elements(all_charsets)-1) return NULL; @@ -560,7 +533,7 @@ CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags) { uint cs_number; CHARSET_INFO *cs; - (void) init_available_charsets(MYF(0)); /* If it isn't initialized */ + my_pthread_once(&charsets_initialized, init_available_charsets); cs_number=get_collation_number(cs_name); cs= cs_number ? get_internal_charset(cs_number,flags) : NULL; @@ -585,7 +558,7 @@ CHARSET_INFO *get_charset_by_csname(const char *cs_name, DBUG_ENTER("get_charset_by_csname"); DBUG_PRINT("enter",("name: '%s'", cs_name)); - (void) init_available_charsets(MYF(0)); /* If it isn't initialized */ + my_pthread_once(&charsets_initialized, init_available_charsets); cs_number= get_charset_number(cs_name, cs_flags); cs= cs_number ? get_internal_charset(cs_number, flags) : NULL; diff --git a/mysys/my_init.c b/mysys/my_init.c index a60927be693..453c72f999f 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -165,7 +165,6 @@ void my_end(int infoflag) my_print_open_files(); } } - free_charsets(); my_error_unregister_all(); my_once_free(); diff --git a/mysys/my_winthread.c b/mysys/my_winthread.c index e94369bec32..ef2a20c2ddc 100644 --- a/mysys/my_winthread.c +++ b/mysys/my_winthread.c @@ -137,4 +137,36 @@ int win_pthread_setspecific(void *a,void *b,uint length) return 0; } + +/* + One time initialization. For simplicity, we assume initializer thread + does not exit within init_routine(). +*/ +int my_pthread_once(my_pthread_once_t *once_control, + void (*init_routine)(void)) +{ + LONG state= InterlockedCompareExchange(once_control, MY_PTHREAD_ONCE_INPROGRESS, + MY_PTHREAD_ONCE_INIT); + switch(state) + { + case MY_PTHREAD_ONCE_INIT: + /* This is initializer thread */ + (*init_routine)(); + *once_control= MY_PTHREAD_ONCE_DONE; + break; + + case MY_PTHREAD_ONCE_INPROGRESS: + /* init_routine in progress. Wait for its completion */ + while(*once_control == MY_PTHREAD_ONCE_INPROGRESS) + { + Sleep(1); + } + break; + case MY_PTHREAD_ONCE_DONE: + /* Nothing to do */ + break; + } + return 0; +} + #endif diff --git a/netware/libmysqlmain.c b/netware/libmysqlmain.c index 03fdb832176..2b6ea9b7e27 100644 --- a/netware/libmysqlmain.c +++ b/netware/libmysqlmain.c @@ -18,7 +18,7 @@ #include "my_global.h" -my_bool init_available_charsets(myf myflags); +void init_available_charsets(void); /* this function is required so that global memory is allocated against this library nlm, and not against a paticular client */ @@ -31,7 +31,7 @@ int _NonAppStart(void *NLMHandle, void *errorScreen, const char *commandLine, { mysql_server_init(0, NULL, NULL); - init_available_charsets(MYF(0)); + init_available_charsets(); return 0; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9aff751ad2f..b145c5ace10 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1287,7 +1287,6 @@ void clean_up(bool print_message) lex_free(); /* Free some memory */ item_create_cleanup(); set_var_free(); - free_charsets(); if (!opt_noacl) { #ifdef HAVE_DLOPEN From c08e6c8867db16245732101ee8603efc0773c7c4 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Sun, 13 Dec 2009 23:29:50 +0300 Subject: [PATCH 038/157] Bug #42849: innodb crash with varying time_zone on partitioned timestamp primary key Since TIMESTAMP values are adjusted by the current time zone settings in both numeric and string contexts, using any expressions involving TIMESTAMP values as a (sub)partitioning function leads to undeterministic behavior of partitioned tables. The effect may vary depending on a storage engine, it can be either incorrect data being retrieved or stored, or an assertion failure. The root cause of this is the fact that the calculated partition ID may differ from a previously calculated ID for the same data due to timezone adjustments of the partitioning expression value. Fixed by disabling any expressions involving TIMESTAMP values to be used in partitioning functions with the follwing two exceptions: 1. Creating or altering into a partitioned table that violates the above rule is not allowed, but opening existing such tables results in a warning rather than an error so that such tables could be fixed. 2. UNIX_TIMESTAMP() is the only way to get a timezone-independent value from a TIMESTAMP column, because it returns the internal representation (a time_t value) of a TIMESTAMP argument verbatim. So UNIX_TIMESTAMP(timestamp_column) is allowed and should be used to fix existing tables if one wants to use TIMESTAMP columns with partitioning. mysql-test/r/partition_bug18198.result: Corrected the error. mysql-test/r/partition_error.result: Corrected error texts. Added test cases for bug #42849. mysql-test/t/partition_bug18198.test: Corrected error code. mysql-test/t/partition_error.test: Corrected error codes. Added test cases for bug #42849. sql/item.h: Added is_timezone_dependent_processor() to Item. sql/item_func.h: Added has_timestamp_args() and the implementation of is_timezone_dependent_processor() for Item_func. sql/item_timefunc.h: Added is_timezone_dependent_processor() to Item_func_unix_timestamp. sql/share/errmsg.txt: Renamed ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR to ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR to better reflect the meaning. Adjusted the error message. sql/sql_partition.cc: Modified fix_fields_part_func() to walk through partitioning expression tree with is_timezone_dependent_processor() and issue a warning/error if it depends on the timezone settings. Changed fix_fields_part_func() to a static function since it is not used anywhere except sql_partition.cc sql/sql_partition.h: Removed the unneeded declaration of fix_fields_part_func() since it is now a static function. sql/sql_yacc.yy: ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR -> ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR. --- mysql-test/r/partition_bug18198.result | 2 +- mysql-test/r/partition_error.result | 310 ++++++++++++++++++++- mysql-test/t/partition_bug18198.test | 2 +- mysql-test/t/partition_error.test | 364 ++++++++++++++++++++++++- sql/item.h | 9 + sql/item_func.h | 23 ++ sql/item_timefunc.h | 10 + sql/share/errmsg.txt | 4 +- sql/sql_partition.cc | 39 ++- sql/sql_partition.h | 3 - sql/sql_yacc.yy | 2 +- 11 files changed, 743 insertions(+), 25 deletions(-) diff --git a/mysql-test/r/partition_bug18198.result b/mysql-test/r/partition_bug18198.result index 18d7d904bb0..ee7bf514807 100644 --- a/mysql-test/r/partition_bug18198.result +++ b/mysql-test/r/partition_bug18198.result @@ -126,7 +126,7 @@ ERROR HY000: This partition function is not allowed create table t1 (col1 date) partition by range(unix_timestamp(col1)) (partition p0 values less than (10), partition p1 values less than (30)); -ERROR HY000: This partition function is not allowed +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed create table t1 (col1 datetime) partition by range(week(col1)) (partition p0 values less than (10), partition p1 values less than (30)); diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result index 511806d64bd..b692203823d 100644 --- a/mysql-test/r/partition_error.result +++ b/mysql-test/r/partition_error.result @@ -138,7 +138,7 @@ primary key(a,b)) partition by hash (rand(a)) partitions 2 (partition x1, partition x2); -ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ') +ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ') partitions 2 (partition x1, partition x2)' at line 6 CREATE TABLE t1 ( @@ -149,7 +149,7 @@ primary key(a,b)) partition by range (rand(a)) partitions 2 (partition x1 values less than (0), partition x2 values less than (2)); -ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ') +ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ') partitions 2 (partition x1 values less than (0), partition x2 values less than' at line 6 CREATE TABLE t1 ( @@ -160,7 +160,7 @@ primary key(a,b)) partition by list (rand(a)) partitions 2 (partition x1 values in (1), partition x2 values in (2)); -ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ') +ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ') partitions 2 (partition x1 values in (1), partition x2 values in (2))' at line 6 CREATE TABLE t1 ( @@ -275,7 +275,7 @@ c int not null, primary key (a,b)) partition by key (a) subpartition by hash (rand(a+b)); -ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 7 +ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')' at line 7 CREATE TABLE t1 ( a int not null, b int not null, @@ -372,7 +372,7 @@ partition by range (3+4) partitions 2 (partition x1 values less than (4) tablespace ts1, partition x2 values less than (8) tablespace ts2); -ERROR HY000: Constant/Random expression in (sub)partitioning function is not allowed +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed CREATE TABLE t1 ( a int not null, b int not null, @@ -542,7 +542,7 @@ partition by list (3+4) partitions 2 (partition x1 values in (4) tablespace ts1, partition x2 values in (8) tablespace ts2); -ERROR HY000: Constant/Random expression in (sub)partitioning function is not allowed +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed CREATE TABLE t1 ( a int not null, b int not null, @@ -634,13 +634,13 @@ partition by range (ascii(v)) ERROR HY000: This partition function is not allowed create table t1 (a int) partition by hash (rand(a)); -ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2 +ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')' at line 2 create table t1 (a int) partition by hash(CURTIME() + a); -ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2 +ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')' at line 2 create table t1 (a int) partition by hash (NOW()+a); -ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2 +ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')' at line 2 create table t1 (a int) partition by hash (extract(hour from convert_tz(a, '+00:00', '+00:00'))); ERROR HY000: This partition function is not allowed @@ -651,3 +651,295 @@ ERROR HY000: This partition function is not allowed create table t1 (a char(10)) partition by hash (extractvalue(a,'a')); ERROR HY000: This partition function is not allowed +# +# Bug #42849: innodb crash with varying time_zone on partitioned +# timestamp primary key +# +CREATE TABLE old (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (UNIX_TIMESTAMP(a)) ( +PARTITION p VALUES LESS THAN (1219089600), +PARTITION pmax VALUES LESS THAN MAXVALUE); +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (a) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: The PARTITION function returns the wrong type +ALTER TABLE old +PARTITION BY RANGE (a) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: The PARTITION function returns the wrong type +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (a+0) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (a+0) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (a % 2) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (a % 2) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (ABS(a)) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (ABS(a)) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (CEILING(a)) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (CEILING(a)) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (FLOOR(a)) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (FLOOR(a)) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (TO_DAYS(a)) ( +PARTITION p VALUES LESS THAN (733638), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (TO_DAYS(a)) ( +PARTITION p VALUES LESS THAN (733638), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (DAYOFYEAR(a)) ( +PARTITION p VALUES LESS THAN (231), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (DAYOFYEAR(a)) ( +PARTITION p VALUES LESS THAN (231), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (DAYOFMONTH(a)) ( +PARTITION p VALUES LESS THAN (19), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (DAYOFMONTH(a)) ( +PARTITION p VALUES LESS THAN (19), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (DAYOFWEEK(a)) ( +PARTITION p VALUES LESS THAN (3), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (DAYOFWEEK(a)) ( +PARTITION p VALUES LESS THAN (3), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (MONTH(a)) ( +PARTITION p VALUES LESS THAN (8), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (MONTH(a)) ( +PARTITION p VALUES LESS THAN (8), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (HOUR(a)) ( +PARTITION p VALUES LESS THAN (17), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (HOUR(a)) ( +PARTITION p VALUES LESS THAN (17), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (MINUTE(a)) ( +PARTITION p VALUES LESS THAN (55), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (MINUTE(a)) ( +PARTITION p VALUES LESS THAN (55), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (QUARTER(a)) ( +PARTITION p VALUES LESS THAN (3), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (QUARTER(a)) ( +PARTITION p VALUES LESS THAN (3), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (SECOND(a)) ( +PARTITION p VALUES LESS THAN (7), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (SECOND(a)) ( +PARTITION p VALUES LESS THAN (7), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (YEARWEEK(a)) ( +PARTITION p VALUES LESS THAN (200833), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (YEARWEEK(a)) ( +PARTITION p VALUES LESS THAN (200833), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (YEAR(a)) ( +PARTITION p VALUES LESS THAN (2008), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (YEAR(a)) ( +PARTITION p VALUES LESS THAN (2008), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (WEEKDAY(a)) ( +PARTITION p VALUES LESS THAN (3), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (WEEKDAY(a)) ( +PARTITION p VALUES LESS THAN (3), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (TIME_TO_SEC(a)) ( +PARTITION p VALUES LESS THAN (64507), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (TIME_TO_SEC(a)) ( +PARTITION p VALUES LESS THAN (64507), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (EXTRACT(DAY FROM a)) ( +PARTITION p VALUES LESS THAN (18), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (EXTRACT(DAY FROM a)) ( +PARTITION p VALUES LESS THAN (18), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL, b TIMESTAMP NOT NULL, PRIMARY KEY(a,b)) +PARTITION BY RANGE (DATEDIFF(a, a)) ( +PARTITION p VALUES LESS THAN (18), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (DATEDIFF(a, a)) ( +PARTITION p VALUES LESS THAN (18), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (YEAR(a + 0)) ( +PARTITION p VALUES LESS THAN (2008), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (YEAR(a + 0)) ( +PARTITION p VALUES LESS THAN (2008), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (TO_DAYS(a + '2008-01-01')) ( +PARTITION p VALUES LESS THAN (733638), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (TO_DAYS(a + '2008-01-01')) ( +PARTITION p VALUES LESS THAN (733638), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (YEAR(a + '2008-01-01')) ( +PARTITION p VALUES LESS THAN (2008), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (YEAR(a + '2008-01-01')) ( +PARTITION p VALUES LESS THAN (2008), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old ADD COLUMN b DATE; +CREATE TABLE new (a TIMESTAMP, b DATE) +PARTITION BY RANGE (YEAR(a + b)) ( +PARTITION p VALUES LESS THAN (2008), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (YEAR(a + b)) ( +PARTITION p VALUES LESS THAN (2008), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP, b DATE) +PARTITION BY RANGE (TO_DAYS(a + b)) ( +PARTITION p VALUES LESS THAN (733638), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (TO_DAYS(a + b)) ( +PARTITION p VALUES LESS THAN (733638), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP, b date) +PARTITION BY RANGE (UNIX_TIMESTAMP(a + b)) ( +PARTITION p VALUES LESS THAN (1219089600), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old +PARTITION BY RANGE (UNIX_TIMESTAMP(a + b)) ( +PARTITION p VALUES LESS THAN (1219089600), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +CREATE TABLE new (a TIMESTAMP, b TIMESTAMP) +PARTITION BY RANGE (UNIX_TIMESTAMP(a + b)) ( +PARTITION p VALUES LESS THAN (1219089600), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +ALTER TABLE old MODIFY b TIMESTAMP; +ALTER TABLE old +PARTITION BY RANGE (UNIX_TIMESTAMP(a + b)) ( +PARTITION p VALUES LESS THAN (1219089600), +PARTITION pmax VALUES LESS THAN MAXVALUE); +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed +DROP TABLE old; +End of 5.1 tests diff --git a/mysql-test/t/partition_bug18198.test b/mysql-test/t/partition_bug18198.test index 7f071c6ec9e..720d483e8ed 100644 --- a/mysql-test/t/partition_bug18198.test +++ b/mysql-test/t/partition_bug18198.test @@ -158,7 +158,7 @@ create table t1 (col1 datetime) partition by range(timestampdiff(day,5,col1)) (partition p0 values less than (10), partition p1 values less than (30)); --- error ER_PARTITION_FUNCTION_IS_NOT_ALLOWED +-- error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR create table t1 (col1 date) partition by range(unix_timestamp(col1)) (partition p0 values less than (10), partition p1 values less than (30)); diff --git a/mysql-test/t/partition_error.test b/mysql-test/t/partition_error.test index 49632f95dfb..1f011f36257 100644 --- a/mysql-test/t/partition_error.test +++ b/mysql-test/t/partition_error.test @@ -466,7 +466,7 @@ partitions 2 # # Partition by range, constant partition function not allowed # ---error ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR CREATE TABLE t1 ( a int not null, b int not null, @@ -681,7 +681,7 @@ partition by list (a); # # Partition by list, constant partition function not allowed # ---error ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR CREATE TABLE t1 ( a int not null, b int not null, @@ -840,4 +840,364 @@ partition by range (a + (select count(*) from t1)) create table t1 (a char(10)) partition by hash (extractvalue(a,'a')); +--echo # +--echo # Bug #42849: innodb crash with varying time_zone on partitioned +--echo # timestamp primary key +--echo # +# A correctly partitioned table to test that trying to repartition it using +# timezone-dependent expression will throw an error. +CREATE TABLE old (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (UNIX_TIMESTAMP(a)) ( +PARTITION p VALUES LESS THAN (1219089600), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +# Check that allowed arithmetic/math functions involving TIMESTAMP values result +# in ER_PARTITION_FUNC_NOT_ALLOWED_ERROR when used as a partitioning function + +--error ER_PARTITION_FUNC_NOT_ALLOWED_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (a) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_PARTITION_FUNC_NOT_ALLOWED_ERROR +ALTER TABLE old +PARTITION BY RANGE (a) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (a+0) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (a+0) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (a % 2) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (a % 2) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (ABS(a)) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (ABS(a)) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (CEILING(a)) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (CEILING(a)) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (FLOOR(a)) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (FLOOR(a)) ( +PARTITION p VALUES LESS THAN (20080819), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +# Check that allowed date/time functions involving TIMESTAMP values result +# in ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR when used as a partitioning function + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (TO_DAYS(a)) ( +PARTITION p VALUES LESS THAN (733638), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (TO_DAYS(a)) ( +PARTITION p VALUES LESS THAN (733638), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (DAYOFYEAR(a)) ( +PARTITION p VALUES LESS THAN (231), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (DAYOFYEAR(a)) ( +PARTITION p VALUES LESS THAN (231), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (DAYOFMONTH(a)) ( +PARTITION p VALUES LESS THAN (19), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (DAYOFMONTH(a)) ( +PARTITION p VALUES LESS THAN (19), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (DAYOFWEEK(a)) ( +PARTITION p VALUES LESS THAN (3), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (DAYOFWEEK(a)) ( +PARTITION p VALUES LESS THAN (3), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (MONTH(a)) ( +PARTITION p VALUES LESS THAN (8), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (MONTH(a)) ( +PARTITION p VALUES LESS THAN (8), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (HOUR(a)) ( +PARTITION p VALUES LESS THAN (17), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (HOUR(a)) ( +PARTITION p VALUES LESS THAN (17), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (MINUTE(a)) ( +PARTITION p VALUES LESS THAN (55), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (MINUTE(a)) ( +PARTITION p VALUES LESS THAN (55), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (QUARTER(a)) ( +PARTITION p VALUES LESS THAN (3), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (QUARTER(a)) ( +PARTITION p VALUES LESS THAN (3), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (SECOND(a)) ( +PARTITION p VALUES LESS THAN (7), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (SECOND(a)) ( +PARTITION p VALUES LESS THAN (7), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (YEARWEEK(a)) ( +PARTITION p VALUES LESS THAN (200833), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (YEARWEEK(a)) ( +PARTITION p VALUES LESS THAN (200833), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (YEAR(a)) ( +PARTITION p VALUES LESS THAN (2008), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (YEAR(a)) ( +PARTITION p VALUES LESS THAN (2008), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (WEEKDAY(a)) ( +PARTITION p VALUES LESS THAN (3), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (WEEKDAY(a)) ( +PARTITION p VALUES LESS THAN (3), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (TIME_TO_SEC(a)) ( +PARTITION p VALUES LESS THAN (64507), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (TIME_TO_SEC(a)) ( +PARTITION p VALUES LESS THAN (64507), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (EXTRACT(DAY FROM a)) ( +PARTITION p VALUES LESS THAN (18), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (EXTRACT(DAY FROM a)) ( +PARTITION p VALUES LESS THAN (18), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL, b TIMESTAMP NOT NULL, PRIMARY KEY(a,b)) +PARTITION BY RANGE (DATEDIFF(a, a)) ( +PARTITION p VALUES LESS THAN (18), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (DATEDIFF(a, a)) ( +PARTITION p VALUES LESS THAN (18), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (YEAR(a + 0)) ( +PARTITION p VALUES LESS THAN (2008), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (YEAR(a + 0)) ( +PARTITION p VALUES LESS THAN (2008), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (TO_DAYS(a + '2008-01-01')) ( +PARTITION p VALUES LESS THAN (733638), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (TO_DAYS(a + '2008-01-01')) ( +PARTITION p VALUES LESS THAN (733638), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY) +PARTITION BY RANGE (YEAR(a + '2008-01-01')) ( +PARTITION p VALUES LESS THAN (2008), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (YEAR(a + '2008-01-01')) ( +PARTITION p VALUES LESS THAN (2008), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +ALTER TABLE old ADD COLUMN b DATE; + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP, b DATE) +PARTITION BY RANGE (YEAR(a + b)) ( +PARTITION p VALUES LESS THAN (2008), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (YEAR(a + b)) ( +PARTITION p VALUES LESS THAN (2008), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP, b DATE) +PARTITION BY RANGE (TO_DAYS(a + b)) ( +PARTITION p VALUES LESS THAN (733638), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (TO_DAYS(a + b)) ( +PARTITION p VALUES LESS THAN (733638), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP, b date) +PARTITION BY RANGE (UNIX_TIMESTAMP(a + b)) ( +PARTITION p VALUES LESS THAN (1219089600), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (UNIX_TIMESTAMP(a + b)) ( +PARTITION p VALUES LESS THAN (1219089600), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +CREATE TABLE new (a TIMESTAMP, b TIMESTAMP) +PARTITION BY RANGE (UNIX_TIMESTAMP(a + b)) ( +PARTITION p VALUES LESS THAN (1219089600), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +ALTER TABLE old MODIFY b TIMESTAMP; + +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR +ALTER TABLE old +PARTITION BY RANGE (UNIX_TIMESTAMP(a + b)) ( +PARTITION p VALUES LESS THAN (1219089600), +PARTITION pmax VALUES LESS THAN MAXVALUE); + +DROP TABLE old; + +--echo End of 5.1 tests diff --git a/sql/item.h b/sql/item.h index 3dfcd7c2612..4135ff2b097 100644 --- a/sql/item.h +++ b/sql/item.h @@ -950,6 +950,15 @@ public: virtual Item *equal_fields_propagator(uchar * arg) { return this; } virtual bool set_no_const_sub(uchar *arg) { return FALSE; } virtual Item *replace_equal_field(uchar * arg) { return this; } + /* + Check if an expression value depends on the current timezone. Used by + partitioning code to reject timezone-dependent expressions in a + (sub)partitioning function. + */ + virtual bool is_timezone_dependent_processor(uchar *bool_arg) + { + return FALSE; + } /* For SP local variable returns pointer to Item representing its diff --git a/sql/item_func.h b/sql/item_func.h index 67049af81a2..738f6544204 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -200,6 +200,29 @@ public: null_value=1; return 0.0; } + bool has_timestamp_args() + { + DBUG_ASSERT(fixed == TRUE); + for (uint i= 0; i < arg_count; i++) + { + if (args[i]->type() == Item::FIELD_ITEM && + args[i]->field_type() == MYSQL_TYPE_TIMESTAMP) + return TRUE; + } + return FALSE; + } + /* + We assume the result of any function that has a TIMESTAMP argument to be + timezone-dependent, since a TIMESTAMP value in both numeric and string + contexts is interpreted according to the current timezone. + The only exception is UNIX_TIMESTAMP() which returns the internal + representation of a TIMESTAMP argument verbatim, and thus does not depend on + the timezone. + */ + virtual bool is_timezone_dependent_processor(uchar *bool_arg) + { + return has_timestamp_args(); + } }; diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 9e3c2e8c89f..a7a64090f6c 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -305,6 +305,16 @@ public: Item_func_unix_timestamp(Item *a) :Item_int_func(a) {} longlong val_int(); const char *func_name() const { return "unix_timestamp"; } + bool check_partition_func_processor(uchar *int_arg) {return FALSE;} + /* + UNIX_TIMESTAMP() depends on the current timezone + (and thus may not be used as a partitioning function) + when its argument is NOT of the TIMESTAMP type. + */ + bool is_timezone_dependent_processor(uchar *int_arg) + { + return !has_timestamp_args(); + } void fix_length_and_dec() { decimals=0; diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 7c92c827c87..cc319667060 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5696,8 +5696,8 @@ ER_PARTITION_WRONG_NO_SUBPART_ERROR eng "Wrong number of subpartitions defined, mismatch with previous setting" ger "Falsche Anzahl von Unterpartitionen definiert, stimmt nicht mit vorherigen Einstellungen überein" swe "Antal subpartitioner definierade och antal subpartitioner är inte lika" -ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR - eng "Constant/Random expression in (sub)partitioning function is not allowed" +ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR + eng "Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed" ger "Konstante oder Random-Ausdrücke in (Unter-)Partitionsfunktionen sind nicht erlaubt" swe "Konstanta uttryck eller slumpmässiga uttryck är inte tillåtna (sub)partitioneringsfunktioner" ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 4a50650b6f4..f3f33ab1dd1 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -869,6 +869,8 @@ int check_signed_flag(partition_info *part_info) part_info Reference to partitioning data structure is_sub_part Is the table subpartitioned as well is_field_to_be_setup Flag if we are to set-up field arrays + is_create_table_ind Indicator of whether openfrm was called as part of + CREATE or ALTER TABLE RETURN VALUE TRUE An error occurred, something was wrong with the @@ -891,8 +893,9 @@ int check_signed_flag(partition_info *part_info) on the field object. */ -bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, - bool is_sub_part, bool is_field_to_be_setup) +static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, + bool is_sub_part, bool is_field_to_be_setup, + bool is_create_table_ind) { partition_info *part_info= table->part_info; uint dir_length, home_dir_length; @@ -982,10 +985,31 @@ bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, thd->where= save_where; if (unlikely(func_expr->const_item())) { - my_error(ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR, MYF(0)); + my_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR, MYF(0)); clear_field_flag(table); goto end; } + + /* + We don't allow creating partitions with timezone-dependent expressions as + a (sub)partitioning function, but we want to allow such expressions when + opening existing tables for easier maintenance. This exception should be + deprecated at some point in future so that we always throw an error. + */ + if (func_expr->walk(&Item::is_timezone_dependent_processor, + 0, NULL)) + { + if (is_create_table_ind) + { + my_error(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR, MYF(0)); + goto end; + } + else + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR, + ER(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR)); + } + if ((!is_sub_part) && (error= check_signed_flag(part_info))) goto end; result= FALSE; @@ -1593,7 +1617,8 @@ bool fix_partition_func(THD *thd, TABLE *table, else { if (unlikely(fix_fields_part_func(thd, part_info->subpart_expr, - table, TRUE, TRUE))) + table, TRUE, TRUE, + is_create_table_ind))) goto end; if (unlikely(part_info->subpart_expr->result_type() != INT_RESULT)) { @@ -1621,7 +1646,8 @@ bool fix_partition_func(THD *thd, TABLE *table, else { if (unlikely(fix_fields_part_func(thd, part_info->part_expr, - table, FALSE, TRUE))) + table, FALSE, TRUE, + is_create_table_ind))) goto end; if (unlikely(part_info->part_expr->result_type() != INT_RESULT)) { @@ -1635,7 +1661,8 @@ bool fix_partition_func(THD *thd, TABLE *table, { const char *error_str; if (unlikely(fix_fields_part_func(thd, part_info->part_expr, - table, FALSE, TRUE))) + table, FALSE, TRUE, + is_create_table_ind))) goto end; if (part_info->part_type == RANGE_PARTITION) { diff --git a/sql/sql_partition.h b/sql/sql_partition.h index 282e24f1853..b9efbf25a00 100644 --- a/sql/sql_partition.h +++ b/sql/sql_partition.h @@ -91,9 +91,6 @@ uint32 get_list_array_idx_for_endpoint(partition_info *part_info, uint32 get_partition_id_range_for_endpoint(partition_info *part_info, bool left_endpoint, bool include_endpoint); -bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, - bool is_sub_part, bool is_field_to_be_setup); - bool check_part_func_fields(Field **ptr, bool ok_with_charsets); bool field_is_partition_charset(Field *field); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c40062e5d52..ec6d2cc72cd 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3931,7 +3931,7 @@ part_func_expr: lex->safe_to_cache_query= 1; if (not_corr_func) { - my_parse_error(ER(ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR)); + my_parse_error(ER(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR)); MYSQL_YYABORT; } $$=$1; From 71c54b8c0cb146de893bbf6006b8d21a0ac2a270 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 14 Dec 2009 00:58:16 +0100 Subject: [PATCH 039/157] This is a patch for Bug#48500 5.0 buffer overflow for ER_UPDATE_INFO, or truncated info message in 5.1 5.0.86 has a buffer overflow/crash, and 5.1.40 has a truncated message. errmsg.txt contains this: ER_UPDATE_INFO rum "Linii identificate (matched): %ld Schimbate: %ld Atentionari (warnings): %ld" When that is sprintf'd into a buffer of STRING_BUFFER_USUAL_SIZE size, a buffer overflow can happen. The solution to this is to use MYSQL_ERRMSG_SIZE for the buffer size, instead of STRING_BUFFER_USUAL_SIZE. This will allow longer strings. To avoid potential crashes, we will also use my_snprintf instead of sprintf. sql/sql_update.cc: sing MYSQL_ERRMSG_SIZE instead of STRING_BUFFER_USUAL_SIZE. Using my_snprintf instead of sprintf. --- sql/sql_update.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 06d1bcaa8fb..35ae0febcec 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -600,8 +600,8 @@ int mysql_update(THD *thd, if (error < 0) { - char buff[STRING_BUFFER_USUAL_SIZE]; - sprintf(buff, ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated, + char buff[MYSQL_ERRMSG_SIZE]; + my_snprintf(buff, sizeof(buff), ER(ER_UPDATE_INFO), (ulong) found, (ulong) updated, (ulong) thd->cuted_fields); thd->row_count_func= (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated; From 97a5d25938945835dd06c24a579bf9d4a2d2f4c2 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Mon, 14 Dec 2009 09:06:46 +0300 Subject: [PATCH 040/157] Post-merge test fix for bug #42849. --- mysql-test/r/partition.result | 12 ++++++------ mysql-test/t/partition.test | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 7e14a0ea7c8..08357795046 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -24,8 +24,8 @@ a timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, b varchar(10), PRIMARY KEY (a) ) -PARTITION BY RANGE (to_days(a)) ( -PARTITION p1 VALUES LESS THAN (733407), +PARTITION BY RANGE (UNIX_TIMESTAMP(a)) ( +PARTITION p1 VALUES LESS THAN (1199134800), PARTITION pmax VALUES LESS THAN MAXVALUE ); INSERT INTO t1 VALUES ('2007-07-30 17:35:48', 'p1'); @@ -37,7 +37,7 @@ a b 2009-07-14 17:35:55 pmax 2009-09-21 17:31:42 pmax ALTER TABLE t1 REORGANIZE PARTITION pmax INTO ( -PARTITION p3 VALUES LESS THAN (733969), +PARTITION p3 VALUES LESS THAN (1247688000), PARTITION pmax VALUES LESS THAN MAXVALUE); SELECT * FROM t1; a b @@ -51,9 +51,9 @@ t1 CREATE TABLE `t1` ( `b` varchar(10) DEFAULT NULL, PRIMARY KEY (`a`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 -/*!50100 PARTITION BY RANGE (to_days(a)) -(PARTITION p1 VALUES LESS THAN (733407) ENGINE = MyISAM, - PARTITION p3 VALUES LESS THAN (733969) ENGINE = MyISAM, +/*!50100 PARTITION BY RANGE (UNIX_TIMESTAMP(a)) +(PARTITION p1 VALUES LESS THAN (1199134800) ENGINE = MyISAM, + PARTITION p3 VALUES LESS THAN (1247688000) ENGINE = MyISAM, PARTITION pmax VALUES LESS THAN MAXVALUE ENGINE = MyISAM) */ DROP TABLE t1; create table t1 (a int NOT NULL, b varchar(5) NOT NULL) diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 0ff4b118426..0cbe389dadd 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -53,8 +53,8 @@ CREATE TABLE t1 ( b varchar(10), PRIMARY KEY (a) ) -PARTITION BY RANGE (to_days(a)) ( - PARTITION p1 VALUES LESS THAN (733407), +PARTITION BY RANGE (UNIX_TIMESTAMP(a)) ( + PARTITION p1 VALUES LESS THAN (1199134800), PARTITION pmax VALUES LESS THAN MAXVALUE ); @@ -64,7 +64,7 @@ INSERT INTO t1 VALUES ('2009-09-21 17:31:42', 'pmax'); SELECT * FROM t1; ALTER TABLE t1 REORGANIZE PARTITION pmax INTO ( - PARTITION p3 VALUES LESS THAN (733969), + PARTITION p3 VALUES LESS THAN (1247688000), PARTITION pmax VALUES LESS THAN MAXVALUE); SELECT * FROM t1; SHOW CREATE TABLE t1; From f0ef41058c80f4c21a243f69ca8686956972e471 Mon Sep 17 00:00:00 2001 From: Satya B Date: Mon, 14 Dec 2009 13:42:26 +0530 Subject: [PATCH 041/157] Fix for BUG#49502 - CMake error compiling 5.1 on Windows When applying innodb snapshot 1.0.6 the storage engine name for innodb plugin under windows was changed from INNODB_PLUGIN to INNOBASE. This is a wrong and changing back the name to INNODB_PLUGIN. storage/innodb_plugin/CMakeLists.txt: Fix for BUG#49502 - CMake error compiling 5.1 on Windows Change the storage engine name to INNODB_PLUGIN in CMakeLists.txt --- storage/innodb_plugin/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innodb_plugin/CMakeLists.txt b/storage/innodb_plugin/CMakeLists.txt index ad483779152..25cd212a473 100644 --- a/storage/innodb_plugin/CMakeLists.txt +++ b/storage/innodb_plugin/CMakeLists.txt @@ -81,4 +81,4 @@ SET(INNODB_PLUGIN_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea ut/ut0byte.c ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c ut/ut0vec.c ut/ut0list.c ut/ut0wqueue.c) ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION) -MYSQL_STORAGE_ENGINE(INNOBASE) +MYSQL_STORAGE_ENGINE(INNODB_PLUGIN) From f9e48efb917bc8f03882e2141ed66099e51392eb Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Mon, 14 Dec 2009 16:11:47 +0100 Subject: [PATCH 042/157] Recommit of patch for bug#49028 for 5.1. Includes both patch from bug#48737 (without test, which should go to next-mr) and test for bug#49028. --- mysql-test/r/ctype_ucs.result | 20 ++++++++++++++++++++ mysql-test/t/ctype_ucs.test | 10 ++++++++++ strings/ctype-ucs2.c | 10 ---------- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 428629e7e9e..abb21b7cee7 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -116,6 +116,26 @@ select binary 'a a' > 'a', binary 'a \0' > 'a', binary 'a\0' > 'a'; binary 'a a' > 'a' binary 'a \0' > 'a' binary 'a\0' > 'a' 1 1 1 SET CHARACTER SET koi8r; +create table t1 (a varchar(2) character set ucs2 collate ucs2_bin, key(a)); +insert into t1 values ('A'),('A'),('B'),('C'),('D'),('A\t'); +insert into t1 values ('A\0'),('A\0'),('A\0'),('A\0'),('AZ'); +select hex(a) from t1 where a like 'A_' order by a; +hex(a) +00410000 +00410000 +00410000 +00410000 +00410009 +0041005A +select hex(a) from t1 ignore key(a) where a like 'A_' order by a; +hex(a) +00410000 +00410000 +00410000 +00410000 +00410009 +0041005A +drop table t1; CREATE TABLE t1 (word VARCHAR(64) CHARACTER SET ucs2, word2 CHAR(64) CHARACTER SET ucs2); INSERT INTO t1 VALUES (_koi8r'ò',_koi8r'ò'), (X'2004',X'2004'); SELECT hex(word) FROM t1 ORDER BY word; diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index e247110658b..310576b9478 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -14,6 +14,16 @@ SET character_set_connection=ucs2; SET CHARACTER SET koi8r; +# +# BUG#49028, error in LIKE with ucs2 +# +create table t1 (a varchar(2) character set ucs2 collate ucs2_bin, key(a)); +insert into t1 values ('A'),('A'),('B'),('C'),('D'),('A\t'); +insert into t1 values ('A\0'),('A\0'),('A\0'),('A\0'),('AZ'); +select hex(a) from t1 where a like 'A_' order by a; +select hex(a) from t1 ignore key(a) where a like 'A_' order by a; +drop table t1; + # # Check that 0x20 is only trimmed when it is # a part of real SPACE character, not just a part diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index a1c691a462b..cead55f8a0a 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1602,16 +1602,6 @@ fill_max_and_min: *min_str++= *max_str++ = ptr[1]; } - /* Temporary fix for handling w_one at end of string (key compression) */ - { - char *tmp; - for (tmp= min_str ; tmp-1 > min_org && tmp[-1] == '\0' && tmp[-2]=='\0';) - { - *--tmp=' '; - *--tmp='\0'; - } - } - *min_length= *max_length = (size_t) (min_str - min_org); while (min_str + 1 < min_end) { From 8948664470e7293b0d767e4e4eadacee1f584b9a Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Mon, 14 Dec 2009 18:50:22 +0200 Subject: [PATCH 043/157] correction to the earlier merging: s/return/DBUG_RETURN/ --- sql/rpl_rli.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index f45ab56aa1c..1263b7c52d9 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -1033,7 +1033,7 @@ bool Relay_log_info::is_until_satisfied(THD *thd, Log_event *ev) if (until_condition == UNTIL_MASTER_POS) { if (ev && ev->server_id == (uint32) ::server_id && !replicate_same_server_id) - return FALSE; + DBUG_RETURN(FALSE); log_name= group_master_log_name; log_pos= (!ev)? group_master_log_pos : ((thd->options & OPTION_BEGIN || !ev->log_pos) ? From 3718eb790016a052b74989efa5961c570cea6e2e Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Mon, 14 Dec 2009 20:27:43 +0300 Subject: [PATCH 044/157] Post-push fixes for the bug #42849: All tests in the parts suite that use partitioning on a timezone-dependent expression were commented out, since it is not valid anymore. --- .../parts/inc/part_blocked_sql_funcs_main.inc | 14 ++- .../suite/parts/inc/partition_timestamp.inc | 82 +++++++------ .../r/part_blocked_sql_func_innodb.result | 98 ---------------- .../r/part_blocked_sql_func_myisam.result | 98 ---------------- .../parts/r/partition_datetime_innodb.result | 108 ------------------ .../parts/r/partition_datetime_myisam.result | 108 ------------------ 6 files changed, 54 insertions(+), 454 deletions(-) diff --git a/mysql-test/suite/parts/inc/part_blocked_sql_funcs_main.inc b/mysql-test/suite/parts/inc/part_blocked_sql_funcs_main.inc index 1a66a26312a..be02e4e0402 100644 --- a/mysql-test/suite/parts/inc/part_blocked_sql_funcs_main.inc +++ b/mysql-test/suite/parts/inc/part_blocked_sql_funcs_main.inc @@ -152,10 +152,16 @@ let $valsqlfunc = timestampdiff(YEAR,'2002-05-01','2001-01-01'); let $coltype = datetime; --source suite/parts/inc/partition_blocked_sql_funcs.inc -let $sqlfunc = unix_timestamp(col1); -let $valsqlfunc = unix_timestamp ('2002-05-01'); -let $coltype = date; ---source suite/parts/inc/partition_blocked_sql_funcs.inc +################################################################################ +# After the fix for bug #42849 the server behavior does not fit into this test's +# architecture: for UNIX_TIMESTAMP() some of the queries in +# suite/parts/inc/partition_blocked_sql_funcs.inc will fail with a different +# error (ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR) and some will succeed where +################################################################################ +#let $sqlfunc = unix_timestamp(col1); +#let $valsqlfunc = unix_timestamp ('2002-05-01'); +#let $coltype = date; +#--source suite/parts/inc/partition_blocked_sql_funcs.inc let $sqlfunc = week(col1); let $valsqlfunc = week('2002-05-01'); diff --git a/mysql-test/suite/parts/inc/partition_timestamp.inc b/mysql-test/suite/parts/inc/partition_timestamp.inc index d152c82a76f..4cf61c155bc 100644 --- a/mysql-test/suite/parts/inc/partition_timestamp.inc +++ b/mysql-test/suite/parts/inc/partition_timestamp.inc @@ -33,42 +33,48 @@ select count(*) from t2; select * from t2; drop table t2; -eval create table t3 (a timestamp not null, primary key(a)) engine=$engine -partition by range (month(a)) subpartition by key (a) -subpartitions 3 ( -partition quarter1 values less than (4), -partition quarter2 values less than (7), -partition quarter3 values less than (10), -partition quarter4 values less than (13) -); -show create table t3; -let $count=12; ---echo $count inserts; -while ($count) -{ -eval insert into t3 values (date_add('1970-01-01 00:00:00',interval $count-1 month)); -dec $count; -} -select count(*) from t3; -select * from t3; -drop table t3; +################################################################################ +# The following 2 tests are no longer valid after bug #42849 has been fixed: +# it is not possible to use a timezone-dependent (such as month(timestamp_col) +# or just a timestamp_col in a numeric context) anymore. +################################################################################ -eval create table t4 (a timestamp not null, primary key(a)) engine=$engine -partition by list (month(a)) subpartition by key (a) -subpartitions 3 ( -partition quarter1 values in (0,1,2,3), -partition quarter2 values in (4,5,6), -partition quarter3 values in (7,8,9), -partition quarter4 values in (10,11,12) -); -show create table t4; -let $count=12; ---echo $count inserts; -while ($count) -{ -eval insert into t4 values (date_add('1970-01-01 00:00:00',interval $count-1 month)); -dec $count; -} -select count(*) from t4; -select * from t4; -drop table t4; +# eval create table t3 (a timestamp not null, primary key(a)) engine=$engine +# partition by range (month(a)) subpartition by key (a) +# subpartitions 3 ( +# partition quarter1 values less than (4), +# partition quarter2 values less than (7), +# partition quarter3 values less than (10), +# partition quarter4 values less than (13) +# ); +# show create table t3; +# let $count=12; +# --echo $count inserts; +# while ($count) +# { +# eval insert into t3 values (date_add('1970-01-01 00:00:00',interval $count-1 month)); +# dec $count; +# } +# select count(*) from t3; +# select * from t3; +# drop table t3; + +# eval create table t4 (a timestamp not null, primary key(a)) engine=$engine +# partition by list (month(a)) subpartition by key (a) +# subpartitions 3 ( +# partition quarter1 values in (0,1,2,3), +# partition quarter2 values in (4,5,6), +# partition quarter3 values in (7,8,9), +# partition quarter4 values in (10,11,12) +# ); +# show create table t4; +# let $count=12; +# --echo $count inserts; +# while ($count) +# { +# eval insert into t4 values (date_add('1970-01-01 00:00:00',interval $count-1 month)); +# dec $count; +# } +# select count(*) from t4; +# select * from t4; +# drop table t4; diff --git a/mysql-test/suite/parts/r/part_blocked_sql_func_innodb.result b/mysql-test/suite/parts/r/part_blocked_sql_func_innodb.result index 57a7b2189ba..21d9548d658 100644 --- a/mysql-test/suite/parts/r/part_blocked_sql_func_innodb.result +++ b/mysql-test/suite/parts/r/part_blocked_sql_func_innodb.result @@ -2942,104 +2942,6 @@ drop table if exists t44 ; drop table if exists t55 ; drop table if exists t66 ; ------------------------------------------------------------------------- ---- unix_timestamp(col1) in partition with coltype date -------------------------------------------------------------------------- -must all fail! -drop table if exists t1 ; -drop table if exists t2 ; -drop table if exists t3 ; -drop table if exists t4 ; -drop table if exists t5 ; -drop table if exists t6 ; -create table t1 (col1 date) engine='INNODB' -partition by range(unix_timestamp(col1)) -(partition p0 values less than (15), -partition p1 values less than (31)); -Got one of the listed errors -create table t2 (col1 date) engine='INNODB' -partition by list(unix_timestamp(col1)) -(partition p0 values in (1,2,3,4,5,6,7,8,9,10), -partition p1 values in (11,12,13,14,15,16,17,18,19,20), -partition p2 values in (21,22,23,24,25,26,27,28,29,30)); -Got one of the listed errors -create table t3 (col1 date) engine='INNODB' -partition by hash(unix_timestamp(col1)); -Got one of the listed errors -create table t4 (colint int, col1 date) engine='INNODB' -partition by range(colint) -subpartition by hash(unix_timestamp(col1)) subpartitions 2 -(partition p0 values less than (15), -partition p1 values less than (31)); -Got one of the listed errors -create table t5 (colint int, col1 date) engine='INNODB' -partition by list(colint) -subpartition by hash(unix_timestamp(col1)) subpartitions 2 -(partition p0 values in (1,2,3,4,5,6,7,8,9,10), -partition p1 values in (11,12,13,14,15,16,17,18,19,20), -partition p2 values in (21,22,23,24,25,26,27,28,29,30)); -Got one of the listed errors -create table t6 (colint int, col1 date) engine='INNODB' -partition by range(colint) -(partition p0 values less than (unix_timestamp ('2002-05-01')), -partition p1 values less than maxvalue); -Got one of the listed errors -drop table if exists t11 ; -drop table if exists t22 ; -drop table if exists t33 ; -drop table if exists t44 ; -drop table if exists t55 ; -drop table if exists t66 ; -create table t11 (col1 date) engine='INNODB' ; -create table t22 (col1 date) engine='INNODB' ; -create table t33 (col1 date) engine='INNODB' ; -create table t44 (colint int, col1 date) engine='INNODB' ; -create table t55 (colint int, col1 date) engine='INNODB' ; -create table t66 (colint int, col1 date) engine='INNODB' ; -alter table t11 -partition by range(unix_timestamp(col1)) -(partition p0 values less than (15), -partition p1 values less than (31)); -Got one of the listed errors -alter table t22 -partition by list(unix_timestamp(col1)) -(partition p0 values in (1,2,3,4,5,6,7,8,9,10), -partition p1 values in (11,12,13,14,15,16,17,18,19,20), -partition p2 values in (21,22,23,24,25,26,27,28,29,30)); -Got one of the listed errors -alter table t33 -partition by hash(unix_timestamp(col1)); -Got one of the listed errors -alter table t44 -partition by range(colint) -subpartition by hash(unix_timestamp(col1)) subpartitions 2 -(partition p0 values less than (15), -partition p1 values less than (31)); -Got one of the listed errors -alter table t55 -partition by list(colint) -subpartition by hash(unix_timestamp(col1)) subpartitions 2 -(partition p0 values in (1,2,3,4,5,6,7,8,9,10), -partition p1 values in (11,12,13,14,15,16,17,18,19,20), -partition p2 values in (21,22,23,24,25,26,27,28,29,30)); -Got one of the listed errors -alter table t66 -partition by range(colint) -(partition p0 values less than (unix_timestamp ('2002-05-01')), -partition p1 values less than maxvalue); -Got one of the listed errors -drop table if exists t1 ; -drop table if exists t2 ; -drop table if exists t3 ; -drop table if exists t4 ; -drop table if exists t5 ; -drop table if exists t6 ; -drop table if exists t11 ; -drop table if exists t22 ; -drop table if exists t33 ; -drop table if exists t44 ; -drop table if exists t55 ; -drop table if exists t66 ; -------------------------------------------------------------------------- --- week(col1) in partition with coltype datetime ------------------------------------------------------------------------- must all fail! diff --git a/mysql-test/suite/parts/r/part_blocked_sql_func_myisam.result b/mysql-test/suite/parts/r/part_blocked_sql_func_myisam.result index 4a67054e82a..cf1a222a6ea 100644 --- a/mysql-test/suite/parts/r/part_blocked_sql_func_myisam.result +++ b/mysql-test/suite/parts/r/part_blocked_sql_func_myisam.result @@ -2942,104 +2942,6 @@ drop table if exists t44 ; drop table if exists t55 ; drop table if exists t66 ; ------------------------------------------------------------------------- ---- unix_timestamp(col1) in partition with coltype date -------------------------------------------------------------------------- -must all fail! -drop table if exists t1 ; -drop table if exists t2 ; -drop table if exists t3 ; -drop table if exists t4 ; -drop table if exists t5 ; -drop table if exists t6 ; -create table t1 (col1 date) engine='MYISAM' -partition by range(unix_timestamp(col1)) -(partition p0 values less than (15), -partition p1 values less than (31)); -Got one of the listed errors -create table t2 (col1 date) engine='MYISAM' -partition by list(unix_timestamp(col1)) -(partition p0 values in (1,2,3,4,5,6,7,8,9,10), -partition p1 values in (11,12,13,14,15,16,17,18,19,20), -partition p2 values in (21,22,23,24,25,26,27,28,29,30)); -Got one of the listed errors -create table t3 (col1 date) engine='MYISAM' -partition by hash(unix_timestamp(col1)); -Got one of the listed errors -create table t4 (colint int, col1 date) engine='MYISAM' -partition by range(colint) -subpartition by hash(unix_timestamp(col1)) subpartitions 2 -(partition p0 values less than (15), -partition p1 values less than (31)); -Got one of the listed errors -create table t5 (colint int, col1 date) engine='MYISAM' -partition by list(colint) -subpartition by hash(unix_timestamp(col1)) subpartitions 2 -(partition p0 values in (1,2,3,4,5,6,7,8,9,10), -partition p1 values in (11,12,13,14,15,16,17,18,19,20), -partition p2 values in (21,22,23,24,25,26,27,28,29,30)); -Got one of the listed errors -create table t6 (colint int, col1 date) engine='MYISAM' -partition by range(colint) -(partition p0 values less than (unix_timestamp ('2002-05-01')), -partition p1 values less than maxvalue); -Got one of the listed errors -drop table if exists t11 ; -drop table if exists t22 ; -drop table if exists t33 ; -drop table if exists t44 ; -drop table if exists t55 ; -drop table if exists t66 ; -create table t11 (col1 date) engine='MYISAM' ; -create table t22 (col1 date) engine='MYISAM' ; -create table t33 (col1 date) engine='MYISAM' ; -create table t44 (colint int, col1 date) engine='MYISAM' ; -create table t55 (colint int, col1 date) engine='MYISAM' ; -create table t66 (colint int, col1 date) engine='MYISAM' ; -alter table t11 -partition by range(unix_timestamp(col1)) -(partition p0 values less than (15), -partition p1 values less than (31)); -Got one of the listed errors -alter table t22 -partition by list(unix_timestamp(col1)) -(partition p0 values in (1,2,3,4,5,6,7,8,9,10), -partition p1 values in (11,12,13,14,15,16,17,18,19,20), -partition p2 values in (21,22,23,24,25,26,27,28,29,30)); -Got one of the listed errors -alter table t33 -partition by hash(unix_timestamp(col1)); -Got one of the listed errors -alter table t44 -partition by range(colint) -subpartition by hash(unix_timestamp(col1)) subpartitions 2 -(partition p0 values less than (15), -partition p1 values less than (31)); -Got one of the listed errors -alter table t55 -partition by list(colint) -subpartition by hash(unix_timestamp(col1)) subpartitions 2 -(partition p0 values in (1,2,3,4,5,6,7,8,9,10), -partition p1 values in (11,12,13,14,15,16,17,18,19,20), -partition p2 values in (21,22,23,24,25,26,27,28,29,30)); -Got one of the listed errors -alter table t66 -partition by range(colint) -(partition p0 values less than (unix_timestamp ('2002-05-01')), -partition p1 values less than maxvalue); -Got one of the listed errors -drop table if exists t1 ; -drop table if exists t2 ; -drop table if exists t3 ; -drop table if exists t4 ; -drop table if exists t5 ; -drop table if exists t6 ; -drop table if exists t11 ; -drop table if exists t22 ; -drop table if exists t33 ; -drop table if exists t44 ; -drop table if exists t55 ; -drop table if exists t66 ; -------------------------------------------------------------------------- --- week(col1) in partition with coltype datetime ------------------------------------------------------------------------- must all fail! diff --git a/mysql-test/suite/parts/r/partition_datetime_innodb.result b/mysql-test/suite/parts/r/partition_datetime_innodb.result index 67517ff5943..48af3343d9a 100644 --- a/mysql-test/suite/parts/r/partition_datetime_innodb.result +++ b/mysql-test/suite/parts/r/partition_datetime_innodb.result @@ -184,114 +184,6 @@ a 1971-01-01 00:00:58 1971-01-01 00:00:59 drop table t2; -create table t3 (a timestamp not null, primary key(a)) engine='InnoDB' -partition by range (month(a)) subpartition by key (a) -subpartitions 3 ( -partition quarter1 values less than (4), -partition quarter2 values less than (7), -partition quarter3 values less than (10), -partition quarter4 values less than (13) -); -show create table t3; -Table Create Table -t3 CREATE TABLE `t3` ( - `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY (`a`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 -/*!50100 PARTITION BY RANGE (month(a)) -SUBPARTITION BY KEY (a) -SUBPARTITIONS 3 -(PARTITION quarter1 VALUES LESS THAN (4) ENGINE = InnoDB, - PARTITION quarter2 VALUES LESS THAN (7) ENGINE = InnoDB, - PARTITION quarter3 VALUES LESS THAN (10) ENGINE = InnoDB, - PARTITION quarter4 VALUES LESS THAN (13) ENGINE = InnoDB) */ -12 inserts; -insert into t3 values (date_add('1970-01-01 00:00:00',interval 12-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 11-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 10-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 9-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 8-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 7-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 6-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 5-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 4-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 3-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 2-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 1-1 month)); -Warnings: -Warning 1264 Out of range value for column 'a' at row 1 -select count(*) from t3; -count(*) -12 -select * from t3; -a -0000-00-00 00:00:00 -1970-02-01 00:00:00 -1970-03-01 00:00:00 -1970-04-01 00:00:00 -1970-05-01 00:00:00 -1970-06-01 00:00:00 -1970-07-01 00:00:00 -1970-08-01 00:00:00 -1970-09-01 00:00:00 -1970-10-01 00:00:00 -1970-11-01 00:00:00 -1970-12-01 00:00:00 -drop table t3; -create table t4 (a timestamp not null, primary key(a)) engine='InnoDB' -partition by list (month(a)) subpartition by key (a) -subpartitions 3 ( -partition quarter1 values in (0,1,2,3), -partition quarter2 values in (4,5,6), -partition quarter3 values in (7,8,9), -partition quarter4 values in (10,11,12) -); -show create table t4; -Table Create Table -t4 CREATE TABLE `t4` ( - `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY (`a`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 -/*!50100 PARTITION BY LIST (month(a)) -SUBPARTITION BY KEY (a) -SUBPARTITIONS 3 -(PARTITION quarter1 VALUES IN (0,1,2,3) ENGINE = InnoDB, - PARTITION quarter2 VALUES IN (4,5,6) ENGINE = InnoDB, - PARTITION quarter3 VALUES IN (7,8,9) ENGINE = InnoDB, - PARTITION quarter4 VALUES IN (10,11,12) ENGINE = InnoDB) */ -12 inserts; -insert into t4 values (date_add('1970-01-01 00:00:00',interval 12-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 11-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 10-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 9-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 8-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 7-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 6-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 5-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 4-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 3-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 2-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 1-1 month)); -Warnings: -Warning 1264 Out of range value for column 'a' at row 1 -select count(*) from t4; -count(*) -12 -select * from t4; -a -0000-00-00 00:00:00 -1970-02-01 00:00:00 -1970-03-01 00:00:00 -1970-04-01 00:00:00 -1970-05-01 00:00:00 -1970-06-01 00:00:00 -1970-07-01 00:00:00 -1970-08-01 00:00:00 -1970-09-01 00:00:00 -1970-10-01 00:00:00 -1970-11-01 00:00:00 -1970-12-01 00:00:00 -drop table t4; create table t1 (a date not null, primary key(a)) engine='InnoDB' partition by key (a) ( partition pa1 max_rows=20 min_rows=2, diff --git a/mysql-test/suite/parts/r/partition_datetime_myisam.result b/mysql-test/suite/parts/r/partition_datetime_myisam.result index ad542870e65..146f291546e 100644 --- a/mysql-test/suite/parts/r/partition_datetime_myisam.result +++ b/mysql-test/suite/parts/r/partition_datetime_myisam.result @@ -184,114 +184,6 @@ a 1971-01-01 00:00:58 1971-01-01 00:00:59 drop table t2; -create table t3 (a timestamp not null, primary key(a)) engine='MyISAM' -partition by range (month(a)) subpartition by key (a) -subpartitions 3 ( -partition quarter1 values less than (4), -partition quarter2 values less than (7), -partition quarter3 values less than (10), -partition quarter4 values less than (13) -); -show create table t3; -Table Create Table -t3 CREATE TABLE `t3` ( - `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY (`a`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1 -/*!50100 PARTITION BY RANGE (month(a)) -SUBPARTITION BY KEY (a) -SUBPARTITIONS 3 -(PARTITION quarter1 VALUES LESS THAN (4) ENGINE = MyISAM, - PARTITION quarter2 VALUES LESS THAN (7) ENGINE = MyISAM, - PARTITION quarter3 VALUES LESS THAN (10) ENGINE = MyISAM, - PARTITION quarter4 VALUES LESS THAN (13) ENGINE = MyISAM) */ -12 inserts; -insert into t3 values (date_add('1970-01-01 00:00:00',interval 12-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 11-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 10-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 9-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 8-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 7-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 6-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 5-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 4-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 3-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 2-1 month)); -insert into t3 values (date_add('1970-01-01 00:00:00',interval 1-1 month)); -Warnings: -Warning 1264 Out of range value for column 'a' at row 1 -select count(*) from t3; -count(*) -12 -select * from t3; -a -0000-00-00 00:00:00 -1970-02-01 00:00:00 -1970-03-01 00:00:00 -1970-04-01 00:00:00 -1970-05-01 00:00:00 -1970-06-01 00:00:00 -1970-07-01 00:00:00 -1970-08-01 00:00:00 -1970-09-01 00:00:00 -1970-10-01 00:00:00 -1970-11-01 00:00:00 -1970-12-01 00:00:00 -drop table t3; -create table t4 (a timestamp not null, primary key(a)) engine='MyISAM' -partition by list (month(a)) subpartition by key (a) -subpartitions 3 ( -partition quarter1 values in (0,1,2,3), -partition quarter2 values in (4,5,6), -partition quarter3 values in (7,8,9), -partition quarter4 values in (10,11,12) -); -show create table t4; -Table Create Table -t4 CREATE TABLE `t4` ( - `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - PRIMARY KEY (`a`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1 -/*!50100 PARTITION BY LIST (month(a)) -SUBPARTITION BY KEY (a) -SUBPARTITIONS 3 -(PARTITION quarter1 VALUES IN (0,1,2,3) ENGINE = MyISAM, - PARTITION quarter2 VALUES IN (4,5,6) ENGINE = MyISAM, - PARTITION quarter3 VALUES IN (7,8,9) ENGINE = MyISAM, - PARTITION quarter4 VALUES IN (10,11,12) ENGINE = MyISAM) */ -12 inserts; -insert into t4 values (date_add('1970-01-01 00:00:00',interval 12-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 11-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 10-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 9-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 8-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 7-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 6-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 5-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 4-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 3-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 2-1 month)); -insert into t4 values (date_add('1970-01-01 00:00:00',interval 1-1 month)); -Warnings: -Warning 1264 Out of range value for column 'a' at row 1 -select count(*) from t4; -count(*) -12 -select * from t4; -a -0000-00-00 00:00:00 -1970-02-01 00:00:00 -1970-03-01 00:00:00 -1970-04-01 00:00:00 -1970-05-01 00:00:00 -1970-06-01 00:00:00 -1970-07-01 00:00:00 -1970-08-01 00:00:00 -1970-09-01 00:00:00 -1970-10-01 00:00:00 -1970-11-01 00:00:00 -1970-12-01 00:00:00 -drop table t4; create table t1 (a date not null, primary key(a)) engine='MyISAM' partition by key (a) ( partition pa1 max_rows=20 min_rows=2, From e813587b4042c95efa6bfd590b3fdbac47c7e8aa Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 15 Dec 2009 13:14:14 +0800 Subject: [PATCH 045/157] Bug #34628 LOAD DATA CONCURRENT INFILE drops CONCURRENT in binary log 'LOAD DATA CONCURRENT [LOCAL] INFILE ...' statment only is binlogged as 'LOAD DATA [LOCAL] INFILE ...' in SBR and MBR. As a result, if replication is on, queries on slaves will be blocked by the replication SQL thread. This patch write code to write 'CONCURRENT' into the log event if 'CONCURRENT' option is in the original statement in SBR and MBR. --- mysql-test/extra/rpl_tests/rpl_loaddata.test | 60 +++++--- mysql-test/suite/rpl/r/rpl_loaddata.result | 18 +-- .../rpl/r/rpl_loaddata_concurrent.result | 128 ++++++++++++++++++ .../suite/rpl/t/rpl_loaddata_concurrent.test | 12 ++ sql/log_event.cc | 4 + sql/log_event.h | 2 +- 6 files changed, 193 insertions(+), 31 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_loaddata_concurrent.result create mode 100644 mysql-test/suite/rpl/t/rpl_loaddata_concurrent.test diff --git a/mysql-test/extra/rpl_tests/rpl_loaddata.test b/mysql-test/extra/rpl_tests/rpl_loaddata.test index 7db12600456..948b77959f0 100644 --- a/mysql-test/extra/rpl_tests/rpl_loaddata.test +++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test @@ -21,14 +21,26 @@ connection slave; reset master; connection master; +# MTR is not case-sensitive. +let $lower_stmt_head= load data; +let $UPPER_STMT_HEAD= LOAD DATA; +if (`SELECT '$lock_option' <> ''`) +{ + #if $lock_option is null, an extra blank is added into the statement, + #this will change the result of rpl_loaddata test case. so $lock_option + #is set only when it is not null. + let $lower_stmt_head= load data $lock_option; + let $UPPER_STMT_HEAD= LOAD DATA $lock_option; +} + select last_insert_id(); create table t1(a int not null auto_increment, b int, primary key(a) ); -load data infile '../../std_data/rpl_loaddata.dat' into table t1; +eval $lower_stmt_head infile '../../std_data/rpl_loaddata.dat' into table t1; # verify that LAST_INSERT_ID() is set by LOAD DATA INFILE select last_insert_id(); create temporary table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60)); -load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by '\n##\n' starting by '>' ignore 1 lines; +eval $lower_stmt_head infile '../../std_data/rpl_loaddata2.dat' into table t2 fields terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by '\n##\n' starting by '>' ignore 1 lines; create table t3 (day date,id int(9),category enum('a','b','c'),name varchar(60)); insert into t3 select * from t2; @@ -56,7 +68,7 @@ sync_with_master; insert into t1 values(1,10); connection master; -load data infile '../../std_data/rpl_loaddata.dat' into table t1; +eval $lower_stmt_head infile '../../std_data/rpl_loaddata.dat' into table t1; save_master_pos; connection slave; @@ -70,9 +82,11 @@ connection slave; set global sql_slave_skip_counter=1; start slave; sync_with_master; ---replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 8 # 9 # 16 # 23 # 33 # -show slave status; +let $last_error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1); +echo Last_SQL_Errno=$last_error; +let $last_error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1); +echo Last_SQL_Error; +echo $last_error; # Trigger error again to test CHANGE MASTER @@ -80,7 +94,7 @@ connection master; set sql_log_bin=0; delete from t1; set sql_log_bin=1; -load data infile '../../std_data/rpl_loaddata.dat' into table t1; +eval $lower_stmt_head infile '../../std_data/rpl_loaddata.dat' into table t1; save_master_pos; connection slave; # The SQL slave thread should be stopped now. @@ -92,9 +106,11 @@ connection slave; stop slave; change master to master_user='test'; change master to master_user='root'; ---replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 8 # 9 # 16 # 23 # 33 # -show slave status; +let $last_error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1); +echo Last_SQL_Errno=$last_error; +let $last_error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1); +echo Last_SQL_Error; +echo $last_error; # Trigger error again to test RESET SLAVE @@ -105,7 +121,7 @@ connection master; set sql_log_bin=0; delete from t1; set sql_log_bin=1; -load data infile '../../std_data/rpl_loaddata.dat' into table t1; +eval $lower_stmt_head infile '../../std_data/rpl_loaddata.dat' into table t1; save_master_pos; connection slave; # The SQL slave thread should be stopped now. @@ -114,9 +130,11 @@ connection slave; # RESET SLAVE and see if error is cleared in SHOW SLAVE STATUS. stop slave; reset slave; ---replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 8 # 9 # 16 # 23 # 33 # -show slave status; +let $last_error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Errno, 1); +echo Last_SQL_Errno=$last_error; +let $last_error= query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1); +echo Last_SQL_Error; +echo $last_error; # Finally, see if logging is done ok on master for a failing LOAD DATA INFILE @@ -125,7 +143,7 @@ reset master; eval create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60), unique(day)) engine=$engine_type; # no transactions --error ER_DUP_ENTRY -load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields +eval $lower_stmt_head infile '../../std_data/rpl_loaddata2.dat' into table t2 fields terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by '\n##\n' starting by '>' ignore 1 lines; select * from t2; @@ -141,7 +159,7 @@ alter table t2 drop key day; connection master; delete from t2; --error ER_DUP_ENTRY -load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields +eval $lower_stmt_head infile '../../std_data/rpl_loaddata2.dat' into table t2 fields terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by '\n##\n' starting by '>' ignore 1 lines; connection slave; @@ -154,7 +172,7 @@ drop table t1, t2; CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB; --error ER_DUP_ENTRY -LOAD DATA INFILE "../../std_data/words.dat" INTO TABLE t1; +eval $UPPER_STMT_HEAD INFILE "../../std_data/words.dat" INTO TABLE t1; DROP TABLE IF EXISTS t1; @@ -182,17 +200,17 @@ DROP TABLE IF EXISTS t1; -- echo ### assertion: works with cross-referenced database -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1 +-- eval $UPPER_STMT_HEAD LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1 -- eval use $db1 -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR -- echo ### assertion: works with fully qualified name on current database -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1 +-- eval $UPPER_STMT_HEAD LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1 -- echo ### assertion: works without fully qualified name on current database -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE t1 +-- eval $UPPER_STMT_HEAD LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE t1 -- echo ### create connection without default database -- echo ### connect (conn2,localhost,root,,*NO-ONE*); @@ -200,7 +218,7 @@ connect (conn2,localhost,root,,*NO-ONE*); -- connection conn2 -- echo ### assertion: works without stating the default database -- replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --- eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1 +-- eval $UPPER_STMT_HEAD LOCAL INFILE '$MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE $db1.t1 -- echo ### disconnect and switch back to master connection -- disconnect conn2 -- connection master diff --git a/mysql-test/suite/rpl/r/rpl_loaddata.result b/mysql-test/suite/rpl/r/rpl_loaddata.result index ca9c14691b0..a8da9aae68e 100644 --- a/mysql-test/suite/rpl/r/rpl_loaddata.result +++ b/mysql-test/suite/rpl/r/rpl_loaddata.result @@ -34,9 +34,9 @@ insert into t1 values(1,10); load data infile '../../std_data/rpl_loaddata.dat' into table t1; 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 Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 2009 # # master-bin.000001 Yes Yes # 0 0 2009 # None 0 No # No 0 0 +Last_SQL_Errno=0 +Last_SQL_Error + set sql_log_bin=0; delete from t1; set sql_log_bin=1; @@ -44,9 +44,9 @@ load data infile '../../std_data/rpl_loaddata.dat' into table t1; stop slave; 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 Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 2044 # # master-bin.000001 No No # 0 0 2044 # None 0 No # No 0 0 +Last_SQL_Errno=0 +Last_SQL_Error + set global sql_slave_skip_counter=1; start slave; set sql_log_bin=0; @@ -55,9 +55,9 @@ set sql_log_bin=1; load data infile '../../std_data/rpl_loaddata.dat' into table t1; stop slave; reset 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 Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error -# 127.0.0.1 root MASTER_PORT 1 4 # # No No # 0 0 0 # None 0 No # No 0 0 +Last_SQL_Errno=0 +Last_SQL_Error + reset master; create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60), unique(day)) engine=MyISAM; diff --git a/mysql-test/suite/rpl/r/rpl_loaddata_concurrent.result b/mysql-test/suite/rpl/r/rpl_loaddata_concurrent.result new file mode 100644 index 00000000000..1ea9b33c262 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_loaddata_concurrent.result @@ -0,0 +1,128 @@ +CREATE TABLE t1 (c1 char(50)); +LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1; +LOAD DATA CONCURRENT INFILE '../../std_data/words.dat' INTO TABLE t1; +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (c1 char(50)) +master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (c1) ;file_id=# +master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA CONCURRENT INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (c1) ;file_id=# +DROP TABLE t1; +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; +reset master; +select last_insert_id(); +last_insert_id() +0 +create table t1(a int not null auto_increment, b int, primary key(a) ); +load data CONCURRENT infile '../../std_data/rpl_loaddata.dat' into table t1; +select last_insert_id(); +last_insert_id() +1 +create temporary table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60)); +load data CONCURRENT infile '../../std_data/rpl_loaddata2.dat' into table t2 fields terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by '\n##\n' starting by '>' ignore 1 lines; +create table t3 (day date,id int(9),category enum('a','b','c'),name varchar(60)); +insert into t3 select * from t2; +select * from t1; +a b +1 10 +2 15 +select * from t3; +day id category name +2003-02-22 2461 b a a a @ %  ' " a +2003-03-22 2161 c asdf +2003-03-22 2416 a bbbbb +drop table t1; +drop table t2; +drop table t3; +create table t1(a int, b int, unique(b)); +insert into t1 values(1,10); +load data CONCURRENT infile '../../std_data/rpl_loaddata.dat' into table t1; +set global sql_slave_skip_counter=1; +start slave; +Last_SQL_Errno=0 +Last_SQL_Error + +set sql_log_bin=0; +delete from t1; +set sql_log_bin=1; +load data CONCURRENT infile '../../std_data/rpl_loaddata.dat' into table t1; +stop slave; +change master to master_user='test'; +change master to master_user='root'; +Last_SQL_Errno=0 +Last_SQL_Error + +set global sql_slave_skip_counter=1; +start slave; +set sql_log_bin=0; +delete from t1; +set sql_log_bin=1; +load data CONCURRENT infile '../../std_data/rpl_loaddata.dat' into table t1; +stop slave; +reset slave; +Last_SQL_Errno=0 +Last_SQL_Error + +reset master; +create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60), +unique(day)) engine=MyISAM; +load data CONCURRENT infile '../../std_data/rpl_loaddata2.dat' into table t2 fields +terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by +'\n##\n' starting by '>' ignore 1 lines; +ERROR 23000: Duplicate entry '2003-03-22' for key 'day' +select * from t2; +day id category name +2003-02-22 2461 b a a a @ %  ' " a +2003-03-22 2161 c asdf +start slave; +select * from t2; +day id category name +2003-02-22 2461 b a a a @ %  ' " a +2003-03-22 2161 c asdf +alter table t2 drop key day; +delete from t2; +load data CONCURRENT infile '../../std_data/rpl_loaddata2.dat' into table t2 fields +terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by +'\n##\n' starting by '>' ignore 1 lines; +ERROR 23000: Duplicate entry '2003-03-22' for key 'day' +drop table t1, t2; +drop table t1, t2; +CREATE TABLE t1 (word CHAR(20) NOT NULL PRIMARY KEY) ENGINE=INNODB; +LOAD DATA CONCURRENT INFILE "../../std_data/words.dat" INTO TABLE t1; +ERROR 23000: Duplicate entry 'Aarhus' for key 'PRIMARY' +DROP TABLE IF EXISTS t1; +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +drop database if exists b48297_db1; +drop database if exists b42897_db2; +create database b48297_db1; +create database b42897_db2; +use b48297_db1; +CREATE TABLE t1 (c1 VARCHAR(256)) engine=MyISAM;; +use b42897_db2; +### assertion: works with cross-referenced database +LOAD DATA CONCURRENT LOCAL INFILE 'MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE b48297_db1.t1; +use b48297_db1; +### assertion: works with fully qualified name on current database +LOAD DATA CONCURRENT LOCAL INFILE 'MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE b48297_db1.t1; +### assertion: works without fully qualified name on current database +LOAD DATA CONCURRENT LOCAL INFILE 'MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE t1; +### create connection without default database +### connect (conn2,localhost,root,,*NO-ONE*); +### assertion: works without stating the default database +LOAD DATA CONCURRENT LOCAL INFILE 'MYSQLTEST_VARDIR/std_data/loaddata5.dat' INTO TABLE b48297_db1.t1; +### disconnect and switch back to master connection +use b48297_db1; +Comparing tables master:b48297_db1.t1 and slave:b48297_db1.t1 +DROP DATABASE b48297_db1; +DROP DATABASE b42897_db2; diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_concurrent.test b/mysql-test/suite/rpl/t/rpl_loaddata_concurrent.test new file mode 100644 index 00000000000..1276b0f3700 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_loaddata_concurrent.test @@ -0,0 +1,12 @@ +-- source include/not_ndb_default.inc +-- source include/have_log_bin.inc + +CREATE TABLE t1 (c1 char(50)); +LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1; +LOAD DATA CONCURRENT INFILE '../../std_data/words.dat' INTO TABLE t1; +-- source include/show_binlog_events.inc +DROP TABLE t1; + +let $lock_option= CONCURRENT; +let $engine_type=MyISAM; +-- source extra/rpl_tests/rpl_loaddata.test diff --git a/sql/log_event.cc b/sql/log_event.cc index 6686a4634f7..9552bfad27f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -4006,6 +4006,7 @@ uint Load_log_event::get_query_buffer_length() return 5 + db_len + 3 + // "use DB; " 18 + fname_len + 2 + // "LOAD DATA INFILE 'file''" + 11 + // "CONCURRENT " 7 + // LOCAL 9 + // " REPLACE or IGNORE " 13 + table_name_len*2 + // "INTO TABLE `table`" @@ -4033,6 +4034,9 @@ void Load_log_event::print_query(bool need_db, const char *cs, char *buf, pos= strmov(pos, "LOAD DATA "); + if (thd->lex->lock_option == TL_WRITE_CONCURRENT_INSERT) + pos= strmov(pos, "CONCURRENT "); + if (fn_start) *fn_start= pos; diff --git a/sql/log_event.h b/sql/log_event.h index 0b4c63a73af..b3098c04364 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1766,7 +1766,7 @@ private: @verbatim (1) USE db; - (2) LOAD DATA [LOCAL] INFILE 'file_name' + (2) LOAD DATA [CONCURRENT] [LOCAL] INFILE 'file_name' (3) [REPLACE | IGNORE] (4) INTO TABLE 'table_name' (5) [FIELDS From fb7214ae4b3d3c91da9653b34b35c2f61725aa31 Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Tue, 15 Dec 2009 14:48:28 +0800 Subject: [PATCH 046/157] bug#49536 - deadlock on rotate_and_purge when using expire_logs_days Problem is that purge_logs implementation in ndb (ndbcluster_binlog_index_purge_file) calls mysql_parse (with (thd->options & OPTION_BIN_LOG) === 0)) but MYSQL_BIN_LOG first takes LOCK_log and then checks thd->options Solution in this patch, changes so that rotate_and_purge does not hold LOCK_log when calling purge_logs_before_date. I think this is safe as other "purge"-function(s) is called wo/ holding LOCK_log, e.g purge_master_logs --- sql/log.cc | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index f795cdab2ca..1adf92e709c 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4481,6 +4481,9 @@ bool general_log_write(THD *thd, enum enum_server_command command, void MYSQL_BIN_LOG::rotate_and_purge(uint flags) { +#ifdef HAVE_REPLICATION + bool check_purge= false; +#endif if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED)) pthread_mutex_lock(&LOCK_log); if ((flags & RP_FORCE_ROTATE) || @@ -4488,16 +4491,24 @@ void MYSQL_BIN_LOG::rotate_and_purge(uint flags) { new_file_without_locking(); #ifdef HAVE_REPLICATION - if (expire_logs_days) - { - time_t purge_time= my_time(0) - expire_logs_days*24*60*60; - if (purge_time >= 0) - purge_logs_before_date(purge_time); - } + check_purge= true; #endif } if (!(flags & RP_LOCK_LOG_IS_ALREADY_LOCKED)) pthread_mutex_unlock(&LOCK_log); + +#ifdef HAVE_REPLICATION + /* + NOTE: Run purge_logs wo/ holding LOCK_log + as it otherwise will deadlock in ndbcluster_binlog_index_purge_file + */ + if (check_purge && expire_logs_days) + { + time_t purge_time= my_time(0) - expire_logs_days*24*60*60; + if (purge_time >= 0) + purge_logs_before_date(purge_time); + } +#endif } uint MYSQL_BIN_LOG::next_file_id() From 4578a5c61b8c502cdf18bff883f746d3d0bd2b39 Mon Sep 17 00:00:00 2001 From: Jon Olav Hauglid Date: Tue, 15 Dec 2009 10:05:20 +0100 Subject: [PATCH 047/157] Bug #48995 abort missing DBUG_RETURN or .. in function "check_key_in_view" check_key_in_view() had one code branch which returned with "return TRUE" rather than "DBUG_RETURN(TRUE)". Only affected debug builds. No test case added. --- sql/sql_view.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index ae3af0640a3..eca3922f17a 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1771,7 +1771,7 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view) if (!fld->item->fixed && fld->item->fix_fields(thd, &fld->item)) { thd->mark_used_columns= save_mark_used_columns; - return TRUE; + DBUG_RETURN(TRUE); } } thd->mark_used_columns= save_mark_used_columns; From cff23162ec4bfc0c0fa489eb8568de0a3ccdd1ab Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 15 Dec 2009 13:48:29 +0400 Subject: [PATCH 048/157] Bug#49134 5.1 server segfaults with 2byte collation file Problem: add_collation did not check that cs->number is smaller than the number of elements in the array all_charsets[], so server could crash when loading an Index.xml file with a collation ID greater the number of elements (for example when downgrading from 5.5). Fix: adding a condition to check that cs->number is not out of valid range. --- mysql-test/std_data/Index.xml | 7 +++++++ mysys/charset.c | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/mysql-test/std_data/Index.xml b/mysql-test/std_data/Index.xml index 3dc647d8195..b8f61d59203 100644 --- a/mysql-test/std_data/Index.xml +++ b/mysql-test/std_data/Index.xml @@ -8,6 +8,13 @@ + + + a + b + + + diff --git a/mysys/charset.c b/mysys/charset.c index d59be4ab6c7..b1b91d716ba 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -220,7 +220,8 @@ copy_uca_collation(CHARSET_INFO *to, CHARSET_INFO *from) static int add_collation(CHARSET_INFO *cs) { if (cs->name && (cs->number || - (cs->number=get_collation_number_internal(cs->name)))) + (cs->number=get_collation_number_internal(cs->name))) && + cs->number < array_elements(all_charsets)) { if (!all_charsets[cs->number]) { From 188c6f8c7474a0c23282451c592df66048734c04 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 15 Dec 2009 14:20:29 +0200 Subject: [PATCH 049/157] Bug #48709: Assertion failed in sql_select.cc:11782: int join_read_key(JOIN_TAB*) The eq_ref access method TABLE_REF (accessed through JOIN_TAB) to save state and to track if this is the first row it finds or not. This state was not reset on subquery re-execution causing an assert. Fixed by resetting the state before the subquery re-execution. --- mysql-test/r/subselect.result | 25 +++++++++++++++++++++++++ mysql-test/t/subselect.test | 26 ++++++++++++++++++++++++++ sql/sql_select.cc | 5 +++++ 3 files changed, 56 insertions(+) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 665473df3ef..f446d8feec3 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4410,6 +4410,31 @@ WHERE a = 230; MAX(b) (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b) NULL 0 DROP TABLE t1, st1, st2; +# +# Bug #48709: Assertion failed in sql_select.cc:11782: +# int join_read_key(JOIN_TAB*) +# +CREATE TABLE t1 (pk int PRIMARY KEY, int_key int); +INSERT INTO t1 VALUES (10,1), (14,1); +CREATE TABLE t2 (pk int PRIMARY KEY, int_key int); +INSERT INTO t2 VALUES (3,3), (5,NULL), (7,3); +# should have eq_ref for t1 +EXPLAIN +SELECT * FROM t2 outr +WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2) +ORDER BY outr.pk; +id select_type table type possible_keys key key_len ref rows Extra +x x outr ALL x x x x x x +x x t1 eq_ref x x x x x x +x x t2 index x x x x x x +# should not crash on debug binaries +SELECT * FROM t2 outr +WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2) +ORDER BY outr.pk; +pk int_key +3 3 +7 3 +DROP TABLE t1,t2; End of 5.0 tests. CREATE TABLE t1 (a INT, b INT); INSERT INTO t1 VALUES (2,22),(1,11),(2,22); diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 7f2dba00ba8..a4314c45cba 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3368,6 +3368,32 @@ WHERE a = 230; DROP TABLE t1, st1, st2; +--echo # +--echo # Bug #48709: Assertion failed in sql_select.cc:11782: +--echo # int join_read_key(JOIN_TAB*) +--echo # + +CREATE TABLE t1 (pk int PRIMARY KEY, int_key int); +INSERT INTO t1 VALUES (10,1), (14,1); + +CREATE TABLE t2 (pk int PRIMARY KEY, int_key int); +INSERT INTO t2 VALUES (3,3), (5,NULL), (7,3); + +--echo # should have eq_ref for t1 +--replace_column 1 x 2 x 5 x 6 x 7 x 8 x 9 x 10 x +EXPLAIN +SELECT * FROM t2 outr +WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2) +ORDER BY outr.pk; + +--echo # should not crash on debug binaries +SELECT * FROM t2 outr +WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2) +ORDER BY outr.pk; + +DROP TABLE t1,t2; + + --echo End of 5.0 tests. # diff --git a/sql/sql_select.cc b/sql/sql_select.cc index e6980bb2add..cbee09f1fdb 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1622,6 +1622,11 @@ JOIN::reinit() if (join_tab_save) memcpy(join_tab, join_tab_save, sizeof(JOIN_TAB) * tables); + /* need to reset ref access state (see join_read_key) */ + if (join_tab) + for (uint i= 0; i < tables; i++) + join_tab[i].ref.key_err= TRUE; + if (tmp_join) restore_tmp(); From b72f27895826552f0bfe5019559f35cf634e0ffe Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 15 Dec 2009 19:10:06 +0200 Subject: [PATCH 050/157] Bug #48709: Assertion failed in sql_select.cc:11782: int join_read_key(JOIN_TAB*) The eq_ref access method TABLE_REF (accessed through JOIN_TAB) to save state and to track if this is the first row it finds or not. This state was not reset on subquery re-execution causing an assert. Fixed by resetting the state before the subquery re-execution. --- mysql-test/r/subselect.result | 25 +++++++++++++++++++++++++ mysql-test/t/subselect.test | 26 ++++++++++++++++++++++++++ sql/sql_select.cc | 5 +++++ 3 files changed, 56 insertions(+) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 8c239d5c349..09a650c722b 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4502,4 +4502,29 @@ WHERE a = 230; MAX(b) (SELECT COUNT(*) FROM st1,st2 WHERE st2.b <= t1.b) NULL 0 DROP TABLE t1, st1, st2; +# +# Bug #48709: Assertion failed in sql_select.cc:11782: +# int join_read_key(JOIN_TAB*) +# +CREATE TABLE t1 (pk int PRIMARY KEY, int_key int); +INSERT INTO t1 VALUES (10,1), (14,1); +CREATE TABLE t2 (pk int PRIMARY KEY, int_key int); +INSERT INTO t2 VALUES (3,3), (5,NULL), (7,3); +# should have eq_ref for t1 +EXPLAIN +SELECT * FROM t2 outr +WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2) +ORDER BY outr.pk; +id select_type table type possible_keys key key_len ref rows Extra +x x outr ALL x x x x x x +x x t1 eq_ref x x x x x x +x x t2 index x x x x x x +# should not crash on debug binaries +SELECT * FROM t2 outr +WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2) +ORDER BY outr.pk; +pk int_key +3 3 +7 3 +DROP TABLE t1,t2; End of 5.0 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 2b5d36da796..bd12742f0f1 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3481,4 +3481,30 @@ WHERE a = 230; DROP TABLE t1, st1, st2; +--echo # +--echo # Bug #48709: Assertion failed in sql_select.cc:11782: +--echo # int join_read_key(JOIN_TAB*) +--echo # + +CREATE TABLE t1 (pk int PRIMARY KEY, int_key int); +INSERT INTO t1 VALUES (10,1), (14,1); + +CREATE TABLE t2 (pk int PRIMARY KEY, int_key int); +INSERT INTO t2 VALUES (3,3), (5,NULL), (7,3); + +--echo # should have eq_ref for t1 +--replace_column 1 x 2 x 5 x 6 x 7 x 8 x 9 x 10 x +EXPLAIN +SELECT * FROM t2 outr +WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2) +ORDER BY outr.pk; + +--echo # should not crash on debug binaries +SELECT * FROM t2 outr +WHERE outr.int_key NOT IN (SELECT t1.pk FROM t1, t2) +ORDER BY outr.pk; + +DROP TABLE t1,t2; + + --echo End of 5.0 tests. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f655db0fc32..d22a23a10d4 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1553,6 +1553,11 @@ JOIN::reinit() if (join_tab_save) memcpy(join_tab, join_tab_save, sizeof(JOIN_TAB) * tables); + /* need to reset ref access state (see join_read_key) */ + if (join_tab) + for (uint i= 0; i < tables; i++) + join_tab[i].ref.key_err= TRUE; + if (tmp_join) restore_tmp(); From 0b7768bc8d29c18596467d3da14dc1aefcdf9c6c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 16 Dec 2009 12:25:46 +0800 Subject: [PATCH 051/157] Postfix Only relative log events are showed. --- mysql-test/suite/rpl/t/rpl_loaddata_concurrent.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/suite/rpl/t/rpl_loaddata_concurrent.test b/mysql-test/suite/rpl/t/rpl_loaddata_concurrent.test index 1276b0f3700..494a0db79fa 100644 --- a/mysql-test/suite/rpl/t/rpl_loaddata_concurrent.test +++ b/mysql-test/suite/rpl/t/rpl_loaddata_concurrent.test @@ -1,6 +1,7 @@ -- source include/not_ndb_default.inc -- source include/have_log_bin.inc +let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1); CREATE TABLE t1 (c1 char(50)); LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE t1; LOAD DATA CONCURRENT INFILE '../../std_data/words.dat' INTO TABLE t1; From c7d483155bb74b9129eeb50c2c90f8fc3215f323 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 16 Dec 2009 12:41:15 +0800 Subject: [PATCH 052/157] Bug #46827 rpl_circular_for_4_hosts failed on PB2 This test case tests a circular replication of four hosts. A--->B--->C--->D--->A The replicate is slow and needs more time to replicate all data in the circle. The time it spends to replicate, sometimes, is longer than the time that wait_condition.inc spends to wait that all data has been replicated. This cause sporadical failure of this test case. This patch uses sync_slave_with_master to ensure that all data can be replicated successfully in the circle. --- .../suite/rpl/t/rpl_circular_for_4_hosts.test | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test b/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test index a49253f90c1..3633462d68e 100644 --- a/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test +++ b/mysql-test/suite/rpl/t/rpl_circular_for_4_hosts.test @@ -233,16 +233,7 @@ COMMIT; --connection master_a --enable_query_log - ---let $wait_condition= SELECT COUNT(*)=400 FROM t2 WHERE c = 1 ---connection master_a ---source include/wait_condition.inc ---connection master_b ---source include/wait_condition.inc ---connection master_c ---source include/wait_condition.inc ---connection master_d ---source include/wait_condition.inc +--source include/circular_rpl_for_4_hosts_sync.inc --connection master_a SELECT 'Master A',b,COUNT(*) FROM t2 WHERE c = 1 GROUP BY b ORDER BY b; @@ -282,15 +273,7 @@ ROLLBACK; --connection master_a --enable_query_log ---let $wait_condition= SELECT COUNT(*)=200 FROM t2 WHERE c = 2 ---connection master_a ---source include/wait_condition.inc ---connection master_b ---source include/wait_condition.inc ---connection master_c ---source include/wait_condition.inc ---connection master_d ---source include/wait_condition.inc +--source include/circular_rpl_for_4_hosts_sync.inc --connection master_a SELECT 'Master A',b,COUNT(*) FROM t2 WHERE c = 2 GROUP BY b ORDER BY b; From adc17cd41e21cb68d63b9962a97ad075da02999f Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 16 Dec 2009 19:31:19 +0200 Subject: [PATCH 053/157] Bug #48866: mysql.test fails under Fedora 12 strmov() is not guaranteed to work correctly on overlapping source and destination buffers. On some OSes it may work, but Fedora 12 has a stpcpy() that's not working correctly on overlapping buffers. Fixed to use the overlap-safe version of strmov instead. Re-vitalized the overlap-safe version of strmov. --- client/mysql.cc | 2 +- include/m_string.h | 9 +++------ strings/strmov.c | 6 +----- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index e4eabe8de33..5ae58baa694 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -4108,7 +4108,7 @@ char *get_arg(char *line, my_bool get_next_arg) if (*ptr == '\\' && ptr[1]) // escaped character { // Remove the backslash - strmov(ptr, ptr+1); + strmov_overlapp(ptr, ptr+1); } else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype)) { diff --git a/include/m_string.h b/include/m_string.h index c26d0fb9260..5411d0483ea 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -108,9 +108,7 @@ extern char NEAR _dig_vec_lower[]; /* Defined in strtod.c */ extern const double log_10[309]; -#ifdef BAD_STRING_COMPILER -#define strmov(A,B) (memccpy(A,B,0,INT_MAX)-1) -#else +#ifndef strmov #define strmov_overlapp(A,B) strmov(A,B) #define strmake_overlapp(A,B,C) strmake(A,B,C) #endif @@ -171,12 +169,11 @@ extern uint strinstr(const char *str,const char *search); extern uint r_strinstr(reg1 my_string str,int from, reg4 my_string search); extern char *strkey(char *dst,char *head,char *tail,char *flags); extern char *strmake(char *dst,const char *src,uint length); -#ifndef strmake_overlapp -extern char *strmake_overlapp(char *dst,const char *src, uint length); -#endif #ifndef strmov extern char *strmov(char *dst,const char *src); +#else +extern char *strmov_overlapp(char *dst,const char *src); #endif extern char *strnmov(char *dst,const char *src,uint n); extern char *strsuff(const char *src,const char *suffix); diff --git a/strings/strmov.c b/strings/strmov.c index 1393411dd8f..eedf22a4ef1 100644 --- a/strings/strmov.c +++ b/strings/strmov.c @@ -24,13 +24,11 @@ #include #include "m_string.h" -#ifdef BAD_STRING_COMPILER +#ifdef strmov #undef strmov #define strmov strmov_overlapp #endif -#ifndef strmov - #if !defined(MC68000) && !defined(DS90) char *strmov(register char *dst, register const char *src) @@ -53,5 +51,3 @@ char *strmov(dst, src) } #endif - -#endif /* strmov */ From ad4bbb281f091709fdf1795fd5588e2cff93dd77 Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Wed, 16 Dec 2009 19:52:56 +0000 Subject: [PATCH 054/157] BUG#49638 binlog_index fails in mysql-trunk-merge Calling push_warning/push_warning_printf with a level of WARN_LEVEL_ERROR *is* a bug. We should either use my_error(), or WARN_LEVEL_WARN. --- mysql-test/suite/binlog/r/binlog_index.result | 2 +- sql/log.cc | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mysql-test/suite/binlog/r/binlog_index.result b/mysql-test/suite/binlog/r/binlog_index.result index 06d8baf23bf..52d698e9f96 100644 --- a/mysql-test/suite/binlog/r/binlog_index.result +++ b/mysql-test/suite/binlog/r/binlog_index.result @@ -38,7 +38,7 @@ purge binary logs TO 'master-bin.000002'; ERROR HY000: Fatal error during log purge show warnings; Level Code Message -Error 1377 a problem with deleting master-bin.000001; consider examining correspondence of your binlog index file to the actual binlog files +Warning 1377 a problem with deleting master-bin.000001; consider examining correspondence of your binlog index file to the actual binlog files Error 1377 Fatal error during log purge reset master; # crash_purge_before_update_index diff --git a/sql/log.cc b/sql/log.cc index 1adf92e709c..2fd29588922 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3014,7 +3014,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) } else { - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_BINLOG_PURGE_FATAL_ERR, "a problem with deleting %s; " "consider examining correspondence " @@ -3045,7 +3045,7 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) } else { - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_BINLOG_PURGE_FATAL_ERR, "a problem with deleting %s; " "consider examining correspondence " @@ -3481,7 +3481,7 @@ int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space, */ if (thd) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_BINLOG_PURGE_FATAL_ERR, "a problem with getting info on being purged %s; " "consider examining correspondence " @@ -3509,7 +3509,7 @@ int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space, { if (thd) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_BINLOG_PURGE_FATAL_ERR, "a problem with deleting %s and " "reading the binlog index file", @@ -3557,7 +3557,7 @@ int MYSQL_BIN_LOG::purge_index_entry(THD *thd, ulonglong *decrease_log_space, { if (thd) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_BINLOG_PURGE_FATAL_ERR, "a problem with deleting %s; " "consider examining correspondence " @@ -3647,7 +3647,7 @@ int MYSQL_BIN_LOG::purge_logs_before_date(time_t purge_time) */ if (thd) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_BINLOG_PURGE_FATAL_ERR, "a problem with getting info on being purged %s; " "consider examining correspondence " From 4338e06f518aa1d5e4c621b80a5b265afb603f61 Mon Sep 17 00:00:00 2001 From: Magne Mahre Date: Wed, 16 Dec 2009 20:53:56 +0100 Subject: [PATCH 055/157] Bug#47017 rpl_timezone fails on PB-2 with mismatch error The bug is caused by a race condition between the INSERT DELAYED thread and the client thread's FLUSH TABLE. The FLUSH TABLE does not guarantee (as is (wrongly) suggested in the test case) that the INSERT DELAYED is ever executed. The execution of the test case will thus not be deterministic. The fix has been to do a deterministic verification that both threads are complete by checking the content of the table. --- mysql-test/suite/rpl/t/rpl_timezone.test | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/rpl/t/rpl_timezone.test b/mysql-test/suite/rpl/t/rpl_timezone.test index 40a2a4444b9..45d1f12b5d5 100644 --- a/mysql-test/suite/rpl/t/rpl_timezone.test +++ b/mysql-test/suite/rpl/t/rpl_timezone.test @@ -179,8 +179,11 @@ insert into t1 values('2008-12-23 19:39:39',1); --connection master1 SET @@session.time_zone='+02:00'; insert delayed into t1 values ('2008-12-23 19:39:39',2); -# Forces table t1 to be closed and flushes the query cache. -# This makes sure that 'delayed insert' is executed before next statement. + +# wait for the delayed insert to be executed +let $wait_condition= SELECT date FROM t1 WHERE a=2; +--source include/wait_condition.inc + flush table t1; flush logs; select * from t1; From 06be03f77cc1dbd3f52232d98fbab2d220d93fc5 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Thu, 17 Dec 2009 09:55:03 +0400 Subject: [PATCH 056/157] Fix for bug#49465: valgrind warnings and incorrect live checksum... Problem: inserting a record we don't set unused null bits in the record buffer if no default field values used. That may lead to wrong live checksum calculation. Fix: set unused null bits in the record buffer in such cases. mysql-test/r/myisam.result: Fix for bug#49465: valgrind warnings and incorrect live checksum... - test result. mysql-test/t/myisam.test: Fix for bug#49465: valgrind warnings and incorrect live checksum... - test case. sql/sql_insert.cc: Fix for bug#49465: valgrind warnings and incorrect live checksum... - set unused null bits to 1 in the record buffer in case we don't call restore_record() before a fill_record() call (when no default values used). --- mysql-test/r/myisam.result | 15 +++++++++++++++ mysql-test/t/myisam.test | 14 ++++++++++++++ sql/sql_insert.cc | 11 ++++++++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 53bb022147e..9c8e5c2863d 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -1883,4 +1883,19 @@ CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; +# +# Bug #49465: valgrind warnings and incorrect live checksum... +# +CREATE TABLE t1( +a VARCHAR(1), b VARCHAR(1), c VARCHAR(1), +f VARCHAR(1), g VARCHAR(1), h VARCHAR(1), +i VARCHAR(1), j VARCHAR(1), k VARCHAR(1)) CHECKSUM=1; +INSERT INTO t1 VALUES('', '', '', '', '', '', '', '', ''); +CHECKSUM TABLE t1 QUICK; +Table Checksum +test.t1 467455460 +CHECKSUM TABLE t1 EXTENDED; +Table Checksum +test.t1 467455460 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 254b0378aa8..d0a480348a3 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -1225,4 +1225,18 @@ SELECT a FROM t1; CHECK TABLE t1; DROP TABLE t1; + +--echo # +--echo # Bug #49465: valgrind warnings and incorrect live checksum... +--echo # +CREATE TABLE t1( +a VARCHAR(1), b VARCHAR(1), c VARCHAR(1), +f VARCHAR(1), g VARCHAR(1), h VARCHAR(1), +i VARCHAR(1), j VARCHAR(1), k VARCHAR(1)) CHECKSUM=1; +INSERT INTO t1 VALUES('', '', '', '', '', '', '', '', ''); +CHECKSUM TABLE t1 QUICK; +CHECKSUM TABLE t1 EXTENDED; +DROP TABLE t1; + + --echo End of 5.0 tests diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index b0958201795..76d4378a6f1 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -787,12 +787,21 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, restore_record(table,s->default_values); // Get empty record else { + TABLE_SHARE *share= table->s; + /* Fix delete marker. No need to restore rest of record since it will be overwritten by fill_record() anyway (and fill_record() does not use default values in this case). */ - table->record[0][0]= table->s->default_values[0]; + table->record[0][0]= share->default_values[0]; + + /* Fix undefined null_bits. */ + if (share->null_bytes > 1 && share->last_null_bit_pos) + { + table->record[0][share->null_bytes - 1]= + share->default_values[share->null_bytes - 1]; + } } if (fill_record_n_invoke_before_triggers(thd, table->field, *values, 0, table->triggers, From 6863f7dc2d93ef9da13a2c9423eb7d0c92d45636 Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Thu, 17 Dec 2009 10:55:18 +0100 Subject: [PATCH 057/157] Bug#47650: using group by with rollup without indexes returns incorrect results with where An outer join of a const table (outer) and a normal table (inner) with GROUP BY on a field from the outer table would optimize away GROUP BY, and thus trigger the optimization to do away with a temporary table if grouping was performed on columns from the const table, hence executing the query with filesort without temporary table. But this should not be done if there is a non-indexed access to the inner table, since filesort does not handle joins. It expects either ref access, range ditto or table scan. The join condition will thus not be applied. Fixed by always forcing execution with temporary table in the case of ROLLUP with a query involving an outer join. This is a slightly broader class of queries than need fixing, but it is hard to ascertain the position of a ROLLUP field wrt outer join with current query representation. mysql-test/r/join_outer.result: Bug#47650: Test result mysql-test/t/join_outer.test: Bug#47650: Test case sql/sql_select.cc: Bug#47650: Fix --- mysql-test/r/join_outer.result | 35 ++++++++++++++++++++++++++++++++++ mysql-test/t/join_outer.test | 29 ++++++++++++++++++++++++++++ sql/sql_select.cc | 14 +++++++++++++- 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 1e4fc91b8bd..083be3737f7 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -1254,3 +1254,38 @@ SELECT * FROM t1 LEFT JOIN t2 ON e<>0 WHERE c=1 AND d<=>NULL; c e d 1 0 NULL DROP TABLE t1,t2; +# +# Bug#47650: using group by with rollup without indexes returns incorrect +# results with where +# +CREATE TABLE t1 ( a INT ); +INSERT INTO t1 VALUES (1); +CREATE TABLE t2 ( a INT, b INT ); +INSERT INTO t2 VALUES (1, 1),(1, 2),(1, 3),(2, 4),(2, 5); +EXPLAIN +SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b ) +FROM t1 LEFT JOIN t2 USING( a ) +GROUP BY t1.a WITH ROLLUP; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort +1 SIMPLE t2 ALL NULL NULL NULL NULL 5 +SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b ) +FROM t1 LEFT JOIN t2 USING( a ) +GROUP BY t1.a WITH ROLLUP; +a COUNT( t2.b ) SUM( t2.b ) MAX( t2.b ) +1 3 6 3 +NULL 3 6 3 +EXPLAIN +SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b ) +FROM t1 JOIN t2 USING( a ) +GROUP BY t1.a WITH ROLLUP; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 Using filesort +1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using where +SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b ) +FROM t1 JOIN t2 USING( a ) +GROUP BY t1.a WITH ROLLUP; +a COUNT( t2.b ) SUM( t2.b ) MAX( t2.b ) +1 3 6 3 +NULL 3 6 3 +DROP TABLE t1, t2; diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index 35aec71ebb8..aeaa69657c6 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -867,3 +867,32 @@ SELECT * FROM t1 LEFT JOIN t2 ON e<>0 WHERE c=1 AND d<=>NULL; DROP TABLE t1,t2; +--echo # +--echo # Bug#47650: using group by with rollup without indexes returns incorrect +--echo # results with where +--echo # +CREATE TABLE t1 ( a INT ); +INSERT INTO t1 VALUES (1); + +CREATE TABLE t2 ( a INT, b INT ); +INSERT INTO t2 VALUES (1, 1),(1, 2),(1, 3),(2, 4),(2, 5); + +EXPLAIN +SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b ) +FROM t1 LEFT JOIN t2 USING( a ) +GROUP BY t1.a WITH ROLLUP; + +SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b ) +FROM t1 LEFT JOIN t2 USING( a ) +GROUP BY t1.a WITH ROLLUP; + +EXPLAIN +SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b ) +FROM t1 JOIN t2 USING( a ) +GROUP BY t1.a WITH ROLLUP; + +SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b ) +FROM t1 JOIN t2 USING( a ) +GROUP BY t1.a WITH ROLLUP; + +DROP TABLE t1, t2; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index cbee09f1fdb..6383fe63012 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7124,7 +7124,19 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, for (order=first_order; order ; order=order->next) { table_map order_tables=order->item[0]->used_tables(); - if (order->item[0]->with_sum_func) + if (order->item[0]->with_sum_func || + /* + If the outer table of an outer join is const (either by itself or + after applying WHERE condition), grouping on a field from such a + table will be optimized away and filesort without temporary table + will be used unless we prevent that now. Filesort is not fit to + handle joins and the join condition is not applied. We can't detect + the case without an expensive test, however, so we force temporary + table for all queries containing more than one table, ROLLUP, and an + outer join. + */ + (join->tables > 1 && join->rollup.state == ROLLUP::STATE_INITED && + join->outer_join)) *simple_order=0; // Must do a temp table to sort else if (!(order_tables & not_const_tables)) { From cf9966f86f3c6245f33342f2f5498a0c5efa96e4 Mon Sep 17 00:00:00 2001 From: Satya B Date: Thu, 17 Dec 2009 16:55:50 +0530 Subject: [PATCH 058/157] Fix for Bug#37408 - Compressed MyISAM files should not require/use mmap() When compressed myisam files are opened, they are always memory mapped sometimes causing memory swapping problems. When we mmap the myisam compressed tables of size greater than the memory available, the kswapd0 process utilization is very high consuming 30-40% of the cpu. This happens only with linux kernels older than 2.6.9 With newer linux kernels, we don't have this problem of high cpu consumption and this option may not be required. The option 'myisam_mmap_size' is added to limit the amount of memory used for memory mapping of myisam files. This option is not dynamic. The default value on 32 bit system is 4294967295 bytes and on 64 bit system it is 18446744073709547520 bytes. Note: Testcase only tests the option variable. The actual bug has be to tested manually. include/my_global.h: Fix for Bug #37408 - Compressed MyISAM files should not require/use mmap() define SIZE_T_MAX include/myisam.h: Fix for Bug #37408 - Compressed MyISAM files should not require/use mmap() declare 'myisam_mmap_size' and 'myisam_mmap_used' variables and the mutex THR_LOCK_myisam_mmap myisam/mi_packrec.c: Fix for Bug #37408 - Compressed MyISAM files should not require/use mmap() add 'myisam_mmap_size' option which limits the memory available to mmap of myisam files myisam/mi_static.c: Fix for Bug #37408 - Compressed MyISAM files should not require/use mmap() declare 'myisam_mmap_size' and 'myisam_mmap_used' variables and the mutex THR_LOCK_myisam_mmap myisam/myisamdef.h: Fix for Bug #37408 - Compressed MyISAM files should not require/use mmap() move MEMMAP_EXTRA_MARGIN to myisam.h so that it can be used in mysqld.cc mysql-test/r/variables.result: Fix for Bug #37408 - Compressed MyISAM files should not require/use mmap() Testcase for BUG#37408 to test the myisam_mmap_size option mysql-test/t/variables.test: Fix for Bug #37408 - Compressed MyISAM files should not require/use mmap() Testcase for BUG#37408 to test the myisam_mmap_size option mysys/my_thr_init.c: Fix for Bug #37408 - Compressed MyISAM files should not require/use mmap() intialize the lock THR_LOCK_myisam_mmap sql/mysqld.cc: Fix for Bug #37408 - Compressed MyISAM files should not require/use mmap() add the 'myisam_mmap_size' option sql/set_var.cc: Fix for Bug #37408 - Compressed MyISAM files should not require/use mmap() add the 'myisam_mmap_size' to the SHOW VARIABLES list --- include/my_global.h | 3 +++ include/myisam.h | 4 ++++ myisam/mi_packrec.c | 35 ++++++++++++++++++++++++++++++++++- myisam/mi_static.c | 3 ++- myisam/myisamdef.h | 1 - mysql-test/r/variables.result | 6 ++++++ mysql-test/t/variables.test | 6 ++++++ mysys/my_thr_init.c | 6 +++++- sql/mysqld.cc | 7 ++++++- sql/set_var.cc | 12 ++++++++++++ 10 files changed, 78 insertions(+), 5 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index 6910ae092e1..595c7cd793b 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -793,6 +793,9 @@ typedef SOCKET_SIZE_TYPE size_socket; #define DBL_MAX 1.79769313486231470e+308 #define FLT_MAX ((float)3.40282346638528860e+38) #endif +#ifndef SIZE_T_MAX +#define SIZE_T_MAX (~((size_t) 0)) +#endif #ifndef HAVE_FINITE #define finite(x) (1.0 / fabs(x) > 0.0) diff --git a/include/myisam.h b/include/myisam.h index ad585f79608..acc2d689b75 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -270,6 +270,8 @@ extern ulong myisam_bulk_insert_tree_size, myisam_data_pointer_size; /* usually used to check if a symlink points into the mysql data home */ /* which is normally forbidden */ extern int (*myisam_test_invalid_symlink)(const char *filename); +extern ulonglong myisam_mmap_size, myisam_mmap_used; +extern pthread_mutex_t THR_LOCK_myisam_mmap; /* Prototypes for myisam-functions */ @@ -315,6 +317,8 @@ extern int mi_delete_all_rows(struct st_myisam_info *info); extern ulong _mi_calc_blob_length(uint length , const byte *pos); extern uint mi_get_pointer_length(ulonglong file_length, uint def); +#define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for mmap file */ + /* this is used to pass to mysql_myisamchk_table -- by Sasha Pachev */ #define MYISAMCHK_REPAIR 1 /* equivalent to myisamchk -r */ diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c index 75cf45d5434..f04c65da505 100644 --- a/myisam/mi_packrec.c +++ b/myisam/mi_packrec.c @@ -1499,12 +1499,26 @@ my_bool _mi_memmap_file(MI_INFO *info) { byte *file_map; MYISAM_SHARE *share=info->s; + my_bool eom; + DBUG_ENTER("mi_memmap_file"); if (!share->file_map) { my_off_t data_file_length= share->state.state.data_file_length; - if (data_file_length > (my_off_t) (~((size_t) 0)) - MEMMAP_EXTRA_MARGIN) + + if (myisam_mmap_size != SIZE_T_MAX) + { + pthread_mutex_lock(&THR_LOCK_myisam_mmap); + eom= data_file_length > myisam_mmap_size - myisam_mmap_used - MEMMAP_EXTRA_MARGIN; + if (!eom) + myisam_mmap_used+= data_file_length + MEMMAP_EXTRA_MARGIN; + pthread_mutex_unlock(&THR_LOCK_myisam_mmap); + } + else + eom= data_file_length > myisam_mmap_size - MEMMAP_EXTRA_MARGIN; + + if (eom) { DBUG_PRINT("warning", ("File is too large for mmap")); DBUG_RETURN(0); @@ -1513,6 +1527,12 @@ my_bool _mi_memmap_file(MI_INFO *info) data_file_length + MEMMAP_EXTRA_MARGIN) { DBUG_PRINT("warning",("File isn't extended for memmap")); + if (myisam_mmap_size != SIZE_T_MAX) + { + pthread_mutex_lock(&THR_LOCK_myisam_mmap); + myisam_mmap_used-= data_file_length + MEMMAP_EXTRA_MARGIN; + pthread_mutex_unlock(&THR_LOCK_myisam_mmap); + } DBUG_RETURN(0); } file_map=(byte*) @@ -1522,6 +1542,12 @@ my_bool _mi_memmap_file(MI_INFO *info) { DBUG_PRINT("warning",("mmap failed: errno: %d",errno)); my_errno=errno; + if (myisam_mmap_size != SIZE_T_MAX) + { + pthread_mutex_lock(&THR_LOCK_myisam_mmap); + myisam_mmap_used-= data_file_length + MEMMAP_EXTRA_MARGIN; + pthread_mutex_unlock(&THR_LOCK_myisam_mmap); + } DBUG_RETURN(0); } share->file_map= file_map; @@ -1538,6 +1564,13 @@ void _mi_unmap_file(MI_INFO *info) VOID(my_munmap(info->s->file_map, (size_t) info->s->state.state.data_file_length+ MEMMAP_EXTRA_MARGIN)); + + if (myisam_mmap_size != SIZE_T_MAX) + { + pthread_mutex_lock(&THR_LOCK_myisam_mmap); + myisam_mmap_used-= info->s->state.state.data_file_length + MEMMAP_EXTRA_MARGIN; + pthread_mutex_unlock(&THR_LOCK_myisam_mmap); + } } diff --git a/myisam/mi_static.c b/myisam/mi_static.c index ab7d3dc592b..b6464e452d7 100644 --- a/myisam/mi_static.c +++ b/myisam/mi_static.c @@ -40,7 +40,8 @@ ulong myisam_concurrent_insert= 0; my_off_t myisam_max_temp_length= MAX_FILE_SIZE; ulong myisam_bulk_insert_tree_size=8192*1024; ulong myisam_data_pointer_size=4; - +ulonglong myisam_mmap_size= SIZE_T_MAX, myisam_mmap_used= 0; +pthread_mutex_t THR_LOCK_myisam_mmap; static int always_valid(const char *filename __attribute__((unused))) { diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index 4ebd5648d26..13ca945eae8 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -428,7 +428,6 @@ typedef struct st_mi_sort_param #define MI_MAX_BLOCK_LENGTH ((((ulong) 1 << 24)-1) & (~ (ulong) (MI_DYN_ALIGN_SIZE-1))) #define MI_REC_BUFF_OFFSET ALIGN_SIZE(MI_DYN_DELETE_BLOCK_HEADER+sizeof(uint32)) -#define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for file */ #define PACK_TYPE_SELECTED 1 /* Bits in field->pack_type */ #define PACK_TYPE_SPACE_FIELDS 2 diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 496f0b69fb8..e24117187d2 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -904,3 +904,9 @@ set global server_id =@my_server_id; set global slow_launch_time =@my_slow_launch_time; set global storage_engine =@my_storage_engine; set global thread_cache_size =@my_thread_cache_size; +# +# BUG#37408 - Compressed MyISAM files should not require/use mmap() +# +# Test 'myisam_mmap_size' option is not dynamic +SET @@myisam_mmap_size= 500M; +ERROR HY000: Variable 'myisam_mmap_size' is a read only variable diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 91f75cf6cd4..cff6a5a0767 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -765,3 +765,9 @@ set global slow_launch_time =@my_slow_launch_time; set global storage_engine =@my_storage_engine; set global thread_cache_size =@my_thread_cache_size; +--echo # +--echo # BUG#37408 - Compressed MyISAM files should not require/use mmap() +--echo # +--echo # Test 'myisam_mmap_size' option is not dynamic +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SET @@myisam_mmap_size= 500M; diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 64fc99952e9..8dcffaebbbb 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -30,7 +30,9 @@ pthread_key(struct st_my_thread_var, THR_KEY_mysys); #endif /* USE_TLS */ pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open, THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap, - THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads; + THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, + THR_LOCK_myisam_mmap; + pthread_cond_t THR_COND_threads; uint THR_thread_count= 0; uint my_thread_end_wait_time= 5; @@ -143,6 +145,7 @@ my_bool my_thread_global_init(void) pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_isam,MY_MUTEX_INIT_SLOW); pthread_mutex_init(&THR_LOCK_myisam,MY_MUTEX_INIT_SLOW); + pthread_mutex_init(&THR_LOCK_myisam_mmap,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_heap,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST); pthread_mutex_init(&THR_LOCK_charset,MY_MUTEX_INIT_FAST); @@ -208,6 +211,7 @@ void my_thread_global_end(void) pthread_mutex_destroy(&THR_LOCK_lock); pthread_mutex_destroy(&THR_LOCK_isam); pthread_mutex_destroy(&THR_LOCK_myisam); + pthread_mutex_destroy(&THR_LOCK_myisam_mmap); pthread_mutex_destroy(&THR_LOCK_heap); pthread_mutex_destroy(&THR_LOCK_net); pthread_mutex_destroy(&THR_LOCK_charset); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b4eb96ab65a..4b0739cc2d2 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4975,7 +4975,8 @@ enum options_mysqld OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE, OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE, OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE, - OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE, + OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_MMAP_SIZE, + OPT_MYISAM_SORT_BUFFER_SIZE, OPT_MYISAM_STATS_METHOD, OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT, OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT, @@ -6255,6 +6256,10 @@ The minimum value for this variable is 4096.", (gptr*) &max_system_variables.myisam_max_sort_file_size, 0, GET_ULL, REQUIRED_ARG, (longlong) LONG_MAX, 0, (ulonglong) MAX_FILE_SIZE, 0, 1024*1024, 0}, + {"myisam_mmap_size", OPT_MYISAM_MMAP_SIZE, + "Can be used to restrict the total memory used for memory mmaping of myisam files", + (gptr*) &myisam_mmap_size, (gptr*) &myisam_mmap_size, 0, + GET_ULL, REQUIRED_ARG, SIZE_T_MAX, MEMMAP_EXTRA_MARGIN, SIZE_T_MAX, 0, 1, 0}, {"myisam_repair_threads", OPT_MYISAM_REPAIR_THREADS, "Number of threads to use when repairing MyISAM tables. The value of 1 disables parallel repair.", (gptr*) &global_system_variables.myisam_repair_threads, diff --git a/sql/set_var.cc b/sql/set_var.cc index c885f7160e9..4871afd2c56 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -122,6 +122,7 @@ static byte *get_error_count(THD *thd); static byte *get_warning_count(THD *thd); static byte *get_have_innodb(THD *thd); static byte *get_tmpdir(THD *thd); +static byte *get_myisam_mmap_size(THD *thd); /* Variable definition list @@ -623,6 +624,10 @@ sys_var_thd_bool sys_keep_files_on_create("keep_files_on_create", &SV::keep_files_on_create); +static sys_var_readonly sys_myisam_mmap_size("myisam_mmap_size", + OPT_GLOBAL, + SHOW_LONGLONG, + get_myisam_mmap_size); /* @@ -723,6 +728,7 @@ sys_var *sys_variables[]= &sys_multi_range_count, &sys_myisam_data_pointer_size, &sys_myisam_max_sort_file_size, + &sys_myisam_mmap_size, &sys_myisam_repair_threads, &sys_myisam_sort_buffer_size, &sys_myisam_stats_method, @@ -1026,6 +1032,7 @@ struct show_var_st init_vars[]= { {sys_myisam_data_pointer_size.name, (char*) &sys_myisam_data_pointer_size, SHOW_SYS}, {sys_myisam_max_sort_file_size.name, (char*) &sys_myisam_max_sort_file_size, SHOW_SYS}, + {sys_myisam_mmap_size.name, (char*) &sys_myisam_mmap_size, SHOW_SYS}, {"myisam_recover_options", (char*) &myisam_recover_options_str, SHOW_CHAR_PTR}, {sys_myisam_repair_threads.name, (char*) &sys_myisam_repair_threads, SHOW_SYS}, @@ -3181,6 +3188,11 @@ static byte *get_tmpdir(THD *thd) return (byte*)mysql_tmpdir; } +static byte *get_myisam_mmap_size(THD *thd) +{ + return (byte *)&myisam_mmap_size; +} + /**************************************************************************** Main handling of variables: - Initialisation From 522c084631ad581ec8f17b187a689f9b992ca06e Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Thu, 17 Dec 2009 16:34:11 +0200 Subject: [PATCH 059/157] Bug #49740 rpl.rpl_temporary fails in PB2 in mysql-trunk-merge The test allowed random coincidence of connection ids for two concurrent sessions performing CREATE/DROP temp tables. Fixed with correcting the test. The sessions connection ids are not changed from their defaults anymore. --- mysql-test/r/rpl_temporary.result | 2 ++ mysql-test/t/rpl_temporary.test | 2 ++ 2 files changed, 4 insertions(+) diff --git a/mysql-test/r/rpl_temporary.result b/mysql-test/r/rpl_temporary.result index 1326c7491f5..45e1a2776f7 100644 --- a/mysql-test/r/rpl_temporary.result +++ b/mysql-test/r/rpl_temporary.result @@ -16,8 +16,10 @@ ERROR 42000: Access denied; you need the SUPER privilege for this operation SELECT @@session.sql_select_limit = @save_select_limit; @@session.sql_select_limit = @save_select_limit 1 +SET @save_conn_id= connection_id(); SET @@session.pseudo_thread_id=100; SET @@session.pseudo_thread_id=connection_id(); +SET @@session.pseudo_thread_id=@save_conn_id; SET @@session.sql_log_bin=0; SET @@session.sql_log_bin=1; drop table if exists t1,t2; diff --git a/mysql-test/t/rpl_temporary.test b/mysql-test/t/rpl_temporary.test index 4cd538877eb..b85262b565d 100644 --- a/mysql-test/t/rpl_temporary.test +++ b/mysql-test/t/rpl_temporary.test @@ -41,8 +41,10 @@ SET @@session.sql_select_limit=10, @@session.sql_log_bin=0; SELECT @@session.sql_select_limit = @save_select_limit; #shouldn't have changed # Now as root, to be sure it works connection con2; +SET @save_conn_id= connection_id(); SET @@session.pseudo_thread_id=100; SET @@session.pseudo_thread_id=connection_id(); +SET @@session.pseudo_thread_id=@save_conn_id; SET @@session.sql_log_bin=0; SET @@session.sql_log_bin=1; From 06a1df91813ea2c39f7312bcf8af972c7e8a926f Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Thu, 17 Dec 2009 15:58:38 -0200 Subject: [PATCH 060/157] Bug#48983: Bad strmake calls (length one too long) The problem is a somewhat common misusage of the strmake function. The strmake(dst, src, len) function writes at most /len/ bytes to the string pointed to by src, not including the trailing null byte. Hence, if /len/ is the exact length of the destination buffer, a one byte buffer overflow can occur if the length of the source string is equal to or greater than /len/. client/mysqldump.c: Make room for the trailing null byte. libmysql/libmysql.c: Add comment, there is enough room in the buffer. Increase buffer length, two strings are concatenated. libmysqld/lib_sql.cc: Make room for the trailing null byte. mysys/default.c: Make room for the trailing null bytes. mysys/mf_pack.c: Make room for the trailing null byte. server-tools/instance-manager/commands.cc: Copy only if overflow isn't possible in both cases. server-tools/instance-manager/listener.cc: Make room for the trailing null byte. sql/log.cc: Make room for the trailing null byte. sql/sp_pcontext.h: Cosmetic fix. sql/sql_acl.cc: MAX_HOSTNAME already specifies space for the trailing null byte. sql/sql_parse.cc: Make room for the trailing null byte. sql/sql_table.cc: Make room for the trailing null byte. --- client/mysqldump.c | 4 ++-- libmysql/libmysql.c | 7 +++++-- libmysqld/lib_sql.cc | 2 +- mysys/default.c | 2 +- mysys/mf_pack.c | 4 ++-- server-tools/instance-manager/commands.cc | 2 +- server-tools/instance-manager/listener.cc | 2 +- sql/log.cc | 8 ++++---- sql/sp_pcontext.h | 2 +- sql/sql_acl.cc | 4 ++-- sql/sql_parse.cc | 2 +- sql/sql_table.cc | 2 +- 12 files changed, 22 insertions(+), 19 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 1918a657316..9bbf718eebf 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -782,7 +782,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), &err_ptr, &err_len); if (err_len) { - strmake(buff, err_ptr, min(sizeof(buff), err_len)); + strmake(buff, err_ptr, min(sizeof(buff) - 1, err_len)); fprintf(stderr, "Invalid mode to --compatible: %s\n", buff); exit(1); } @@ -3452,7 +3452,7 @@ static ulong find_set(TYPELIB *lib, const char *x, uint length, for (; pos != end && *pos != ','; pos++) ; var_len= (uint) (pos - start); - strmake(buff, start, min(sizeof(buff), var_len)); + strmake(buff, start, min(sizeof(buff) - 1, var_len)); find= find_type(buff, lib, var_len); if (!find) { diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index d287679bebb..62feae1b56e 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -712,7 +712,10 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, if (!passwd) passwd=""; - /* Store user into the buffer */ + /* + Store user into the buffer. + Advance position as strmake returns a pointer to the closing NUL. + */ end= strmake(end, user, USERNAME_LENGTH) + 1; /* write scrambled password according to server capabilities */ @@ -1252,7 +1255,7 @@ mysql_list_fields(MYSQL *mysql, const char *table, const char *wild) { MYSQL_RES *result; MYSQL_FIELD *fields; - char buff[257],*end; + char buff[258],*end; DBUG_ENTER("mysql_list_fields"); DBUG_PRINT("enter",("table: '%s' wild: '%s'",table,wild ? wild : "")); diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index b0a47727c7c..644d4702e55 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -73,7 +73,7 @@ void embedded_get_error(MYSQL *mysql, MYSQL_DATA *data) NET *net= &mysql->net; struct embedded_query_result *ei= data->embedded_info; net->last_errno= ei->last_errno; - strmake(net->last_error, ei->info, sizeof(net->last_error)); + strmake(net->last_error, ei->info, sizeof(net->last_error) - 1); memcpy(net->sqlstate, ei->sqlstate, sizeof(net->sqlstate)); mysql->server_status= ei->server_status; my_free((gptr) data, MYF(0)); diff --git a/mysys/default.c b/mysys/default.c index 362aa0d4605..0d162dc13d5 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -605,7 +605,7 @@ static int search_default_file_with_ext(Process_option_func opt_handler, int recursion_level) { char name[FN_REFLEN + 10], buff[4096], curr_gr[4096], *ptr, *end, **tmp_ext; - char *value, option[4096], tmp[FN_REFLEN]; + char *value, option[4096+2], tmp[FN_REFLEN]; static const char includedir_keyword[]= "includedir"; static const char include_keyword[]= "include"; const int max_recursion_level= 10; diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c index d2bac95b391..3053699f457 100644 --- a/mysys/mf_pack.c +++ b/mysys/mf_pack.c @@ -234,7 +234,7 @@ my_bool my_use_symdir=0; /* Set this if you want to use symdirs */ #ifdef USE_SYMDIR void symdirget(char *dir) { - char buff[FN_REFLEN]; + char buff[FN_REFLEN+1]; char *pos=strend(dir); if (dir[0] && pos[-1] != FN_DEVCHAR && my_access(dir, F_OK)) { @@ -246,7 +246,7 @@ void symdirget(char *dir) *pos++=temp; *pos=0; /* Restore old filename */ if (file >= 0) { - if ((length= my_read(file, buff, sizeof(buff), MYF(0))) > 0) + if ((length= my_read(file, buff, sizeof(buff) - 1, MYF(0))) > 0) { for (pos= buff + length ; pos > buff && (iscntrl(pos[-1]) || isspace(pos[-1])) ; diff --git a/server-tools/instance-manager/commands.cc b/server-tools/instance-manager/commands.cc index bb3763ce8c5..5e8ba5087af 100644 --- a/server-tools/instance-manager/commands.cc +++ b/server-tools/instance-manager/commands.cc @@ -651,7 +651,7 @@ Set_option::Set_option(Instance_map *instance_map_arg, instance_name= instance->options.instance_name; /* add prefix for add_option */ - if ((option_len_arg < MAX_OPTION_LEN - 1) || + if ((option_len_arg < MAX_OPTION_LEN - 1) && (option_value_len_arg < MAX_OPTION_LEN - 1)) { strmake(option, option_arg, option_len_arg); diff --git a/server-tools/instance-manager/listener.cc b/server-tools/instance-manager/listener.cc index 36f0cbe85e1..653a807e5fc 100644 --- a/server-tools/instance-manager/listener.cc +++ b/server-tools/instance-manager/listener.cc @@ -331,7 +331,7 @@ create_unix_socket(struct sockaddr_un &unix_socket_address) unix_socket_address.sun_family= AF_UNIX; strmake(unix_socket_address.sun_path, options.socket_file_name, - sizeof(unix_socket_address.sun_path)); + sizeof(unix_socket_address.sun_path) - 1); unlink(unix_socket_address.sun_path); // in case we have stale socket file /* diff --git a/sql/log.cc b/sql/log.cc index c042651216c..4aeab534b23 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -501,7 +501,7 @@ const char *MYSQL_LOG::generate_name(const char *log_name, { char *p = fn_ext(log_name); uint length=(uint) (p-log_name); - strmake(buff,log_name,min(length,FN_REFLEN)); + strmake(buff, log_name, min(length, FN_REFLEN-1)); return (const char*)buff; } return log_name; @@ -1503,7 +1503,7 @@ int MYSQL_LOG::purge_logs_before_date(time_t purge_time) if (stat_area.st_mtime < purge_time) strmake(to_log, log_info.log_file_name, - sizeof(log_info.log_file_name)); + sizeof(log_info.log_file_name) - 1); else break; } @@ -2604,11 +2604,11 @@ bool flush_error_log() if (opt_error_log) { char err_renamed[FN_REFLEN], *end; - end= strmake(err_renamed,log_error_file,FN_REFLEN-4); + end= strmake(err_renamed,log_error_file,FN_REFLEN-5); strmov(end, "-old"); VOID(pthread_mutex_lock(&LOCK_error_log)); #ifdef __WIN__ - char err_temp[FN_REFLEN+4]; + char err_temp[FN_REFLEN+5]; /* On Windows is necessary a temporary file for to rename the current error file. diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index db8bed349f2..cd3011b2c37 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -71,7 +71,7 @@ typedef struct sp_label typedef struct sp_cond_type { enum { number, state, warning, notfound, exception } type; - char sqlstate[6]; + char sqlstate[SQLSTATE_LENGTH+1]; uint mysqlerr; } sp_cond_type_t; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f29baad9a84..bf117874552 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -914,7 +914,7 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh, *mqh= acl_user->user_resource; if (acl_user->host.hostname) - strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME); + strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME - 1); else *sctx->priv_host= 0; } @@ -1015,7 +1015,7 @@ bool acl_getroot_no_password(Security_context *sctx, char *user, char *host, sctx->priv_user= acl_user->user ? user : (char *) ""; if (acl_user->host.hostname) - strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME); + strmake(sctx->priv_host, acl_user->host.hostname, MAX_HOSTNAME - 1); else *sctx->priv_host= 0; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f34aa3c3bad..48df40f2614 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -917,7 +917,7 @@ static int check_connection(THD *thd) vio_keepalive(net->vio, TRUE); { /* buff[] needs to big enough to hold the server_version variable */ - char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH + 64]; + char buff[SERVER_VERSION_LENGTH + 1 + SCRAMBLE_LENGTH + 1 + 64]; ulong client_flags = (CLIENT_LONG_FLAG | CLIENT_CONNECT_WITH_DB | CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index e32c17bc678..9432c5c3f89 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -742,7 +742,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, !(sql_field->charset= get_charset_by_csname(sql_field->charset->csname, MY_CS_BINSORT,MYF(0)))) { - char tmp[64]; + char tmp[65]; strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4), STRING_WITH_LEN("_bin")); my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp); From f815246486444ca2dc5d408099439e1d973d3a7b Mon Sep 17 00:00:00 2001 From: Magne Mahre Date: Fri, 18 Dec 2009 11:48:34 +0100 Subject: [PATCH 061/157] Backport to 5.1 branch (next-mr revid: 2921) Bug#35589 SET PASSWORD caused a crash Bug#35591 FLUSH PRIVILEGES caused a crash A race condition on the privilege hash tables (proc_priv_hash and func_priv_hash) caused one thread to try to delete elements that had already been deleted by another thread. The bug was caused by reading and saving the pointers to the hash tables outside mutex protection. This led to an inconsistency where a thread copied a pointer to a hash, another thread did the same, the first thread then deleted the hash, and the second then crashed when it in turn tried to delete the deleted hash. The fix is to ensure that operations on the shared hash structures happens under mutex protection (moving the locking up a little) --- sql/sql_acl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 3b81a85c368..b30c012e633 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3765,11 +3765,11 @@ static my_bool grant_reload_procs_priv(THD *thd) DBUG_RETURN(TRUE); } + rw_wrlock(&LOCK_grant); /* Save a copy of the current hash if we need to undo the grant load */ old_proc_priv_hash= proc_priv_hash; old_func_priv_hash= func_priv_hash; - rw_wrlock(&LOCK_grant); if ((return_val= grant_load_procs_priv(table.table))) { /* Error; Reverting to old hash */ From 6559a46a245264eafd1f87ec65097f83d77142bd Mon Sep 17 00:00:00 2001 From: Satya B Date: Mon, 21 Dec 2009 15:41:38 +0530 Subject: [PATCH 062/157] Applying InnoDB snapshot 5.1-ss6344, part 1. Fixes BUG#49267 Detailed revision comments: r6306 | calvin | 2009-12-14 15:12:46 +0200 (Mon, 14 Dec 2009) | 5 lines branches/5.1: fix bug#49267: innodb-autoinc.test fails on windows because of different case mode There is no change to the InnoDB code, only to fix test case by changing "T1" to "t1". --- mysql-test/r/innodb-autoinc.result | 42 +++++++++++++++--------------- mysql-test/t/innodb-autoinc.test | 34 ++++++++++++------------ 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/mysql-test/r/innodb-autoinc.result b/mysql-test/r/innodb-autoinc.result index 2e0d2c1d776..fe87e11c9ec 100644 --- a/mysql-test/r/innodb-autoinc.result +++ b/mysql-test/r/innodb-autoinc.result @@ -1111,46 +1111,46 @@ c1 c2 3 innodb 4 NULL DROP TABLE t1; -CREATE TABLE T1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB; -CREATE INDEX i1 on T1(c2); -SHOW CREATE TABLE T1; +CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB; +CREATE INDEX i1 on t1(c2); +SHOW CREATE TABLE t1; Table Create Table -T1 CREATE TABLE `T1` ( +t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, `c2` int(11) DEFAULT NULL, PRIMARY KEY (`c1`), KEY `i1` (`c2`) ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1 -INSERT INTO T1 (c2) values (0); -SELECT * FROM T1; +INSERT INTO t1 (c2) values (0); +SELECT * FROM t1; c1 c2 10 0 -DROP TABLE T1; -DROP TABLE IF EXISTS T1; +DROP TABLE t1; +DROP TABLE IF EXISTS t1; Warnings: -Note 1051 Unknown table 'T1' -CREATE TABLE T1(C1 DOUBLE AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB; -INSERT INTO T1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb'); -INSERT INTO T1(C2) VALUES ('innodb'); -SHOW CREATE TABLE T1; +Note 1051 Unknown table 't1' +CREATE TABLE t1(C1 DOUBLE AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB; +INSERT INTO t1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb'); +INSERT INTO t1(C2) VALUES ('innodb'); +SHOW CREATE TABLE t1; Table Create Table -T1 CREATE TABLE `T1` ( +t1 CREATE TABLE `t1` ( `C1` double NOT NULL AUTO_INCREMENT, `C2` char(10) DEFAULT NULL, PRIMARY KEY (`C1`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 -DROP TABLE T1; -CREATE TABLE T1(C1 FLOAT AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB; -INSERT INTO T1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb'); -INSERT INTO T1(C2) VALUES ('innodb'); -SHOW CREATE TABLE T1; +DROP TABLE t1; +CREATE TABLE t1(C1 FLOAT AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB; +INSERT INTO t1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb'); +INSERT INTO t1(C2) VALUES ('innodb'); +SHOW CREATE TABLE t1; Table Create Table -T1 CREATE TABLE `T1` ( +t1 CREATE TABLE `t1` ( `C1` float NOT NULL AUTO_INCREMENT, `C2` char(10) DEFAULT NULL, PRIMARY KEY (`C1`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 -DROP TABLE T1; +DROP TABLE t1; DROP TABLE IF EXISTS t1; Warnings: Note 1051 Unknown table 't1' diff --git a/mysql-test/t/innodb-autoinc.test b/mysql-test/t/innodb-autoinc.test index 4fa5ab022ad..84386280a26 100644 --- a/mysql-test/t/innodb-autoinc.test +++ b/mysql-test/t/innodb-autoinc.test @@ -614,31 +614,31 @@ DROP TABLE t1; # 47125: auto_increment start value is ignored if an index is created # and engine=innodb # -CREATE TABLE T1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB; -CREATE INDEX i1 on T1(c2); -SHOW CREATE TABLE T1; -INSERT INTO T1 (c2) values (0); -SELECT * FROM T1; -DROP TABLE T1; +CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB; +CREATE INDEX i1 on t1(c2); +SHOW CREATE TABLE t1; +INSERT INTO t1 (c2) values (0); +SELECT * FROM t1; +DROP TABLE t1; ## # 49032: Use the correct function to read the AUTOINC column value # -DROP TABLE IF EXISTS T1; -CREATE TABLE T1(C1 DOUBLE AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB; -INSERT INTO T1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb'); +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(C1 DOUBLE AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB; +INSERT INTO t1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb'); # Restart the server -- source include/restart_mysqld.inc -INSERT INTO T1(C2) VALUES ('innodb'); -SHOW CREATE TABLE T1; -DROP TABLE T1; -CREATE TABLE T1(C1 FLOAT AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB; -INSERT INTO T1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb'); +INSERT INTO t1(C2) VALUES ('innodb'); +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1(C1 FLOAT AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB; +INSERT INTO t1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb'); # Restart the server -- source include/restart_mysqld.inc -INSERT INTO T1(C2) VALUES ('innodb'); -SHOW CREATE TABLE T1; -DROP TABLE T1; +INSERT INTO t1(C2) VALUES ('innodb'); +SHOW CREATE TABLE t1; +DROP TABLE t1; ## # 47720: REPLACE INTO Autoincrement column with negative values From 2f04df4ab040b5821cf552c27741ede58ebec162 Mon Sep 17 00:00:00 2001 From: Satya B Date: Mon, 21 Dec 2009 15:50:32 +0530 Subject: [PATCH 063/157] Applying InnoDB snapshot 5.1-ss6344, part 2. Fixes BUG#41609 but does not address the printouts issue Detailed revision comments: r6310 | marko | 2009-12-15 15:23:54 +0200 (Tue, 15 Dec 2009) | 30 lines branches/5.1: Merge r4922 from branches/zip. This the fix for the first part of Bug #41609 from InnoDB Plugin to the built-in InnoDB in MySQL 5.1. This allows InnoDB Hot Backup to back up a database while the built-in InnoDB in MySQL 5.1 is creating temporary tables. (This fix does not address the printouts about missing .ibd files for temporary tables at InnoDB startup, which was committed to branches/zip in r6252.) rb://219 approved by Sunny Bains. branches/zip: Distinguish temporary tables in MLOG_FILE_CREATE. This addresses Mantis Issue #23 in InnoDB Hot Backup and some of MySQL Bug #41609. In MLOG_FILE_CREATE, we need to distinguish temporary tables, so that InnoDB Hot Backup can work correctly. It turns out that we can do this easily, by using a bit of the previously unused parameter for page number. (The page number parameter of MLOG_FILE_CREATE has been written as 0 ever since MySQL 4.1, which introduced MLOG_FILE_CREATE.) MLOG_FILE_FLAG_TEMP: A flag for indicating a temporary table in the page number parameter of MLOG_FILE_ operations. fil_op_write_log(): Add the parameter log_flags. fil_op_log_parse_or_replay(): Add the parameter log_flags. Do not replay MLOG_FILE_CREATE when MLOG_FILE_FLAG_TEMP is set in log_flags. This only affects ibbackup --apply-log. InnoDB itself never replays file operations. --- storage/innobase/fil/fil0fil.c | 29 +++++++++++++++++------------ storage/innobase/include/fil0fil.h | 10 +++++----- storage/innobase/include/mtr0mtr.h | 6 ++++++ storage/innobase/log/log0recv.c | 7 +++---- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c index 42e5166c9e4..3810fefd3cb 100644 --- a/storage/innobase/fil/fil0fil.c +++ b/storage/innobase/fil/fil0fil.c @@ -1740,6 +1740,8 @@ fil_op_write_log( MLOG_FILE_DELETE, or MLOG_FILE_RENAME */ ulint space_id, /* in: space id */ + ulint log_flags, /* in: redo log flags (stored + in the page number field) */ const char* name, /* in: table name in the familiar 'databasename/tablename' format, or the file path in the case of @@ -1760,8 +1762,8 @@ fil_op_write_log( return; } - log_ptr = mlog_write_initial_log_record_for_file_op(type, space_id, 0, - log_ptr, mtr); + log_ptr = mlog_write_initial_log_record_for_file_op( + type, space_id, log_flags, log_ptr, mtr); /* Let us store the strings as null-terminated for easier readability and handling */ @@ -1810,11 +1812,11 @@ fil_op_log_parse_or_replay( not fir completely between ptr and end_ptr */ byte* end_ptr, /* in: buffer end */ ulint type, /* in: the type of this log record */ - ibool do_replay, /* in: TRUE if we want to replay the - operation, and not just parse the log record */ - ulint space_id) /* in: if do_replay is TRUE, the space id of - the tablespace in question; otherwise - ignored */ + ulint space_id, /* in: the space id of the tablespace in + question, or 0 if the log record should + only be parsed but not replayed */ + ulint log_flags) /* in: redo log flags + (stored in the page number parameter) */ { ulint name_len; ulint new_name_len; @@ -1868,7 +1870,7 @@ fil_op_log_parse_or_replay( printf("new name %s\n", new_name); } */ - if (do_replay == FALSE) { + if (!space_id) { return(ptr); } @@ -1917,6 +1919,8 @@ fil_op_log_parse_or_replay( } else if (fil_get_space_id_for_table(name) != ULINT_UNDEFINED) { /* Do nothing */ + } else if (log_flags & MLOG_FILE_FLAG_TEMP) { + /* Temporary table, do nothing */ } else { /* Create the database directory for name, if it does not exist yet */ @@ -2078,7 +2082,7 @@ try_again: to write any log record */ mtr_start(&mtr); - fil_op_write_log(MLOG_FILE_DELETE, id, path, NULL, &mtr); + fil_op_write_log(MLOG_FILE_DELETE, id, 0, path, NULL, &mtr); mtr_commit(&mtr); #endif mem_free(path); @@ -2349,7 +2353,7 @@ retry: mtr_start(&mtr); - fil_op_write_log(MLOG_FILE_RENAME, id, old_name, new_name, + fil_op_write_log(MLOG_FILE_RENAME, id, 0, old_name, new_name, &mtr); mtr_commit(&mtr); } @@ -2525,8 +2529,9 @@ error_exit2: mtr_start(&mtr); - fil_op_write_log(MLOG_FILE_CREATE, *space_id, tablename, - NULL, &mtr); + fil_op_write_log(MLOG_FILE_CREATE, *space_id, + is_temp ? MLOG_FILE_FLAG_TEMP : 0, + tablename, NULL, &mtr); mtr_commit(&mtr); } diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 6b8fd4b03d5..251d6c22547 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -330,11 +330,11 @@ fil_op_log_parse_or_replay( not fir completely between ptr and end_ptr */ byte* end_ptr, /* in: buffer end */ ulint type, /* in: the type of this log record */ - ibool do_replay, /* in: TRUE if we want to replay the - operation, and not just parse the log record */ - ulint space_id); /* in: if do_replay is TRUE, the space id of - the tablespace in question; otherwise - ignored */ + ulint space_id, /* in: the space id of the tablespace in + question, or 0 if the log record should + only be parsed but not replayed */ + ulint log_flags); /* in: redo log flags + (stored in the page number parameter) */ /*********************************************************************** Deletes a single-table tablespace. The tablespace must be cached in the memory cache. */ diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index 2a160d27e0c..a6e2976830b 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -134,6 +134,12 @@ flag value must give the length also! */ #define MLOG_BIGGEST_TYPE ((byte)46) /* biggest value (used in asserts) */ +/* Flags for MLOG_FILE operations (stored in the page number +parameter, called log_flags in the functions). The page number +parameter was initially written as 0. */ +#define MLOG_FILE_FLAG_TEMP 1 /* identifies TEMPORARY TABLE in + MLOG_FILE_CREATE */ + /******************************************************************* Starts a mini-transaction and creates a mini-transaction handle and buffer in the memory buffer given by the caller. */ diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index aef58b7b576..5d309768064 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -939,8 +939,7 @@ recv_parse_or_apply_log_rec_body( case MLOG_FILE_CREATE: case MLOG_FILE_RENAME: case MLOG_FILE_DELETE: - ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, FALSE, - ULINT_UNDEFINED); + ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, 0, 0); break; default: ptr = NULL; @@ -1938,8 +1937,8 @@ loop: point to the datadir we should use there */ if (NULL == fil_op_log_parse_or_replay( - body, end_ptr, type, TRUE, - space)) { + body, end_ptr, type, + space, page_no)) { fprintf(stderr, "InnoDB: Error: file op" " log record of type %lu" From 83d5ca950ba1b6e1d5cbc2f39352a30ff7bad8b4 Mon Sep 17 00:00:00 2001 From: Satya B Date: Wed, 23 Dec 2009 12:29:34 +0530 Subject: [PATCH 064/157] Applying InnoDB snapshot 5.1-ss6344, Fixes BUG#47814 and also applying 5.1-ss6355 Detailed revision comments: r6324 | jyang | 2009-12-17 06:54:24 +0200 (Thu, 17 Dec 2009) | 8 lines branches/5.1: Fix bug #47814 - Diagnostics are frequently not printed after a long lock wait in InnoDB. Separate out the lock wait timeout check thread from monitor information printing thread. rb://200 Approved by Marko. r6349 | marko | 2009-12-22 11:09:54 +0200 (Tue, 22 Dec 2009) | 3 lines branches/5.1: lock_print_info_summary(): Remove a reference to innobase_mysql_end_print_arbitrary_thd() that should have been removed in r6347 when removing the function. r6350 | marko | 2009-12-22 11:11:09 +0200 (Tue, 22 Dec 2009) | 1 line branches/5.1: Remove an obsolete declaration of LOCK_thread_count. --- storage/innobase/handler/ha_innodb.cc | 4 +- storage/innobase/include/lock0lock.h | 9 +- storage/innobase/include/srv0srv.h | 26 +++- storage/innobase/lock/lock0lock.c | 22 +++- storage/innobase/log/log0log.c | 2 +- storage/innobase/srv/srv0srv.c | 177 ++++++++++++++++++++------ storage/innobase/srv/srv0start.c | 15 ++- 7 files changed, 194 insertions(+), 61 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 2467e7b19b5..a1b8c551845 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -7394,8 +7394,8 @@ innodb_show_status( mutex_enter_noninline(&srv_monitor_file_mutex); rewind(srv_monitor_file); - srv_printf_innodb_monitor(srv_monitor_file, - &trx_list_start, &trx_list_end); + srv_printf_innodb_monitor(srv_monitor_file, FALSE, + &trx_list_start, &trx_list_end); flen = ftell(srv_monitor_file); os_file_set_eof(srv_monitor_file); diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index 635724bf5a1..beaf17eda01 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -579,10 +579,15 @@ lock_rec_print( /************************************************************************* Prints info of locks for all transactions. */ -void +ibool lock_print_info_summary( /*====================*/ - FILE* file); /* in: file where to print */ + /* out: FALSE if not able to obtain + kernel mutex and exits without + printing info */ + FILE* file, /* in: file where to print */ + ibool nowait);/* in: whether to wait for the kernel + mutex */ /************************************************************************* Prints info of locks for each transaction. */ diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 67144a41d3d..3dd4bb961f9 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -146,7 +146,8 @@ extern ibool srv_print_innodb_tablespace_monitor; extern ibool srv_print_verbose_log; extern ibool srv_print_innodb_table_monitor; -extern ibool srv_lock_timeout_and_monitor_active; +extern ibool srv_lock_timeout_active; +extern ibool srv_monitor_active; extern ibool srv_error_monitor_active; extern ulong srv_n_spin_wait_rounds; @@ -427,12 +428,21 @@ srv_release_mysql_thread_if_suspended( que_thr_t* thr); /* in: query thread associated with the MySQL OS thread */ /************************************************************************* -A thread which wakes up threads whose lock wait may have lasted too long. -This also prints the info output by various InnoDB monitors. */ +A thread which wakes up threads whose lock wait may have lasted too +long. */ os_thread_ret_t -srv_lock_timeout_and_monitor_thread( -/*================================*/ +srv_lock_timeout_thread( +/*====================*/ + /* out: a dummy parameter */ + void* arg); /* in: a dummy parameter required by + os_thread_create */ +/************************************************************************* +A thread which prints the info output by various InnoDB monitors. */ + +os_thread_ret_t +srv_monitor_thread( +/*===============*/ /* out: a dummy parameter */ void* arg); /* in: a dummy parameter required by os_thread_create */ @@ -449,10 +459,14 @@ srv_error_monitor_thread( /********************************************************************** Outputs to a file the output of the InnoDB Monitor. */ -void +ibool srv_printf_innodb_monitor( /*======================*/ + /* out: FALSE if not all information printed + due to failure to obtain necessary mutex */ FILE* file, /* in: output stream */ + ibool nowait, /* in: whether to wait for kernel + mutex. */ ulint* trx_start, /* out: file position of the start of the list of active transactions */ ulint* trx_end); /* out: file position of the end of diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 80aef45ea35..4cc10931060 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -4192,12 +4192,27 @@ lock_get_n_rec_locks(void) /************************************************************************* Prints info of locks for all transactions. */ -void +ibool lock_print_info_summary( /*====================*/ - FILE* file) /* in: file where to print */ + /* out: FALSE if not able to obtain + kernel mutex and exit without + printing lock info */ + FILE* file, /* in: file where to print */ + ibool nowait) /* in: whether to wait for the kernel + mutex */ { - lock_mutex_enter_kernel(); + + /* if nowait is FALSE, wait on the kernel mutex, + otherwise return immediately if fail to obtain the + mutex. */ + if (!nowait) { + lock_mutex_enter_kernel(); + } else if (mutex_enter_nowait(&kernel_mutex)) { + fputs("FAIL TO OBTAIN KERNEL MUTEX, " + "SKIP LOCK INFO PRINTING\n", file); + return(FALSE); + } if (lock_deadlock_found) { fputs("------------------------\n" @@ -4231,6 +4246,7 @@ lock_print_info_summary( "Total number of lock structs in row lock hash table %lu\n", (ulong) lock_get_n_rec_locks()); #endif /* PRINT_NUM_OF_LOCK_STRUCTS */ + return(TRUE); } /************************************************************************* diff --git a/storage/innobase/log/log0log.c b/storage/innobase/log/log0log.c index b10c348b24d..3300997112b 100644 --- a/storage/innobase/log/log0log.c +++ b/storage/innobase/log/log0log.c @@ -3045,7 +3045,7 @@ loop: if (srv_fast_shutdown < 2 && (srv_error_monitor_active - || srv_lock_timeout_and_monitor_active)) { + || srv_lock_timeout_active || srv_monitor_active)) { mutex_exit(&kernel_mutex); diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 71e74ab848b..26ea7958d0d 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -64,7 +64,8 @@ ulint srv_fatal_semaphore_wait_threshold = 600; in microseconds, in order to reduce the lagging of the purge thread. */ ulint srv_dml_needed_delay = 0; -ibool srv_lock_timeout_and_monitor_active = FALSE; +ibool srv_lock_timeout_active = FALSE; +ibool srv_monitor_active = FALSE; ibool srv_error_monitor_active = FALSE; const char* srv_main_thread_op_info = ""; @@ -122,6 +123,16 @@ ulint srv_log_file_size = ULINT_MAX; /* size in database pages */ ulint srv_log_buffer_size = ULINT_MAX; /* size in database pages */ ulong srv_flush_log_at_trx_commit = 1; +/* Maximum number of times allowed to conditionally acquire +mutex before switching to blocking wait on the mutex */ +#define MAX_MUTEX_NOWAIT 20 + +/* Check whether the number of failed nonblocking mutex +acquisition attempts exceeds maximum allowed value. If so, +srv_printf_innodb_monitor() will request mutex acquisition +with mutex_enter(), which will wait until it gets the mutex. */ +#define MUTEX_NOWAIT(mutex_skipped) ((mutex_skipped) < MAX_MUTEX_NOWAIT) + byte srv_latin1_ordering[256] /* The sort order table of the latin1 character set. The following table is the MySQL order as of Feb 10th, 2002 */ @@ -1626,10 +1637,13 @@ srv_refresh_innodb_monitor_stats(void) /********************************************************************** Outputs to a file the output of the InnoDB Monitor. */ -void +ibool srv_printf_innodb_monitor( /*======================*/ + /* out: FALSE if not all information printed + due to failure to obtain necessary mutex */ FILE* file, /* in: output stream */ + ibool nowait, /* in: whether to wait for the mutex. */ ulint* trx_start, /* out: file position of the start of the list of active transactions */ ulint* trx_end) /* out: file position of the end of @@ -1638,6 +1652,7 @@ srv_printf_innodb_monitor( double time_elapsed; time_t current_time; ulint n_reserved; + ibool ret; mutex_enter(&srv_innodb_monitor_mutex); @@ -1682,24 +1697,31 @@ srv_printf_innodb_monitor( mutex_exit(&dict_foreign_err_mutex); - lock_print_info_summary(file); - if (trx_start) { - long t = ftell(file); - if (t < 0) { - *trx_start = ULINT_UNDEFINED; - } else { - *trx_start = (ulint) t; - } - } - lock_print_info_all_transactions(file); - if (trx_end) { - long t = ftell(file); - if (t < 0) { - *trx_end = ULINT_UNDEFINED; - } else { - *trx_end = (ulint) t; + /* Only if lock_print_info_summary proceeds correctly, + before we call the lock_print_info_all_transactions + to print all the lock information. */ + ret = lock_print_info_summary(file, nowait); + + if (ret) { + if (trx_start) { + long t = ftell(file); + if (t < 0) { + *trx_start = ULINT_UNDEFINED; + } else { + *trx_start = (ulint) t; + } + } + lock_print_info_all_transactions(file); + if (trx_end) { + long t = ftell(file); + if (t < 0) { + *trx_end = ULINT_UNDEFINED; + } else { + *trx_end = (ulint) t; + } } } + fputs("--------\n" "FILE I/O\n" "--------\n", file); @@ -1804,6 +1826,8 @@ srv_printf_innodb_monitor( "============================\n", file); mutex_exit(&srv_innodb_monitor_mutex); fflush(file); + + return(ret); } /********************************************************************** @@ -1883,26 +1907,23 @@ srv_export_innodb_status(void) } /************************************************************************* -A thread which wakes up threads whose lock wait may have lasted too long. -This also prints the info output by various InnoDB monitors. */ +A thread prints the info output by various InnoDB monitors. */ os_thread_ret_t -srv_lock_timeout_and_monitor_thread( -/*================================*/ +srv_monitor_thread( +/*===============*/ /* out: a dummy parameter */ void* arg __attribute__((unused))) /* in: a dummy parameter required by os_thread_create */ { - srv_slot_t* slot; double time_elapsed; time_t current_time; time_t last_table_monitor_time; time_t last_tablespace_monitor_time; time_t last_monitor_time; - ibool some_waits; - double wait_time; - ulint i; + ulint mutex_skipped; + ibool last_srv_print_monitor; #ifdef UNIV_DEBUG_THREAD_CREATION fprintf(stderr, "Lock timeout thread starts, id %lu\n", @@ -1913,13 +1934,15 @@ srv_lock_timeout_and_monitor_thread( last_table_monitor_time = time(NULL); last_tablespace_monitor_time = time(NULL); last_monitor_time = time(NULL); + mutex_skipped = 0; + last_srv_print_monitor = srv_print_innodb_monitor; loop: - srv_lock_timeout_and_monitor_active = TRUE; + srv_monitor_active = TRUE; - /* When someone is waiting for a lock, we wake up every second - and check if a timeout has passed for a lock wait */ + /* Wake up every 5 seconds to see if we need to print + monitor information. */ - os_thread_sleep(1000000); + os_thread_sleep(5000000); current_time = time(NULL); @@ -1929,14 +1952,40 @@ loop: last_monitor_time = time(NULL); if (srv_print_innodb_monitor) { - srv_printf_innodb_monitor(stderr, NULL, NULL); + /* Reset mutex_skipped counter everytime + srv_print_innodb_monitor changes. This is to + ensure we will not be blocked by kernel_mutex + for short duration information printing, + such as requested by sync_array_print_long_waits() */ + if (!last_srv_print_monitor) { + mutex_skipped = 0; + last_srv_print_monitor = TRUE; + } + + if (!srv_printf_innodb_monitor(stderr, + MUTEX_NOWAIT(mutex_skipped), + NULL, NULL)) { + mutex_skipped++; + } else { + /* Reset the counter */ + mutex_skipped = 0; + } + } else { + last_srv_print_monitor = FALSE; } + if (srv_innodb_status) { mutex_enter(&srv_monitor_file_mutex); rewind(srv_monitor_file); - srv_printf_innodb_monitor(srv_monitor_file, NULL, - NULL); + if (!srv_printf_innodb_monitor(srv_monitor_file, + MUTEX_NOWAIT(mutex_skipped), + NULL, NULL)) { + mutex_skipped++; + } else { + mutex_skipped = 0; + } + os_file_set_eof(srv_monitor_file); mutex_exit(&srv_monitor_file_mutex); } @@ -1989,6 +2038,56 @@ loop: } } + if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) { + goto exit_func; + } + + if (srv_print_innodb_monitor + || srv_print_innodb_lock_monitor + || srv_print_innodb_tablespace_monitor + || srv_print_innodb_table_monitor) { + goto loop; + } + + srv_monitor_active = FALSE; + + goto loop; + +exit_func: + srv_monitor_active = FALSE; + + /* We count the number of threads in os_thread_exit(). A created + thread should always use that to exit and not use return() to exit. */ + + os_thread_exit(NULL); + + OS_THREAD_DUMMY_RETURN; +} + +/************************************************************************* +A thread which wakes up threads whose lock wait may have lasted too long. */ + +os_thread_ret_t +srv_lock_timeout_thread( +/*====================*/ + /* out: a dummy parameter */ + void* arg __attribute__((unused))) + /* in: a dummy parameter required by + os_thread_create */ +{ + srv_slot_t* slot; + ibool some_waits; + double wait_time; + ulint i; + +loop: + /* When someone is waiting for a lock, we wake up every second + and check if a timeout has passed for a lock wait */ + + os_thread_sleep(1000000); + + srv_lock_timeout_active = TRUE; + mutex_enter(&kernel_mutex); some_waits = FALSE; @@ -2033,17 +2132,11 @@ loop: goto exit_func; } - if (some_waits || srv_print_innodb_monitor - || srv_print_innodb_lock_monitor - || srv_print_innodb_tablespace_monitor - || srv_print_innodb_table_monitor) { + if (some_waits) { goto loop; } - /* No one was waiting for a lock and no monitor was active: - suspend this thread */ - - srv_lock_timeout_and_monitor_active = FALSE; + srv_lock_timeout_active = FALSE; #if 0 /* The following synchronisation is disabled, since @@ -2053,7 +2146,7 @@ loop: goto loop; exit_func: - srv_lock_timeout_and_monitor_active = FALSE; + srv_lock_timeout_active = FALSE; /* We count the number of threads in os_thread_exit(). A created thread should always use that to exit and not use return() to exit. */ diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c index ea88039f3dd..a7950473a17 100644 --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c @@ -87,8 +87,8 @@ static os_file_t files[1000]; static mutex_t ios_mutex; static ulint ios; -static ulint n[SRV_MAX_N_IO_THREADS + 5]; -static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 5]; +static ulint n[SRV_MAX_N_IO_THREADS + 6]; +static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6]; /* We use this mutex to test the return value of pthread_mutex_trylock on successful locking. HP-UX does NOT return 0, though Linux et al do. */ @@ -1596,15 +1596,20 @@ innobase_start_or_create_for_mysql(void) /* fprintf(stderr, "Max allowed record size %lu\n", page_get_free_space_of_empty() / 2); */ - /* Create the thread which watches the timeouts for lock waits - and prints InnoDB monitor info */ + /* Create the thread which watches the timeouts for lock + waits */ - os_thread_create(&srv_lock_timeout_and_monitor_thread, NULL, + os_thread_create(&srv_lock_timeout_thread, NULL, thread_ids + 2 + SRV_MAX_N_IO_THREADS); /* Create the thread which warns of long semaphore waits */ os_thread_create(&srv_error_monitor_thread, NULL, thread_ids + 3 + SRV_MAX_N_IO_THREADS); + + /* Create the thread which prints InnoDB monitor info */ + os_thread_create(&srv_monitor_thread, NULL, + thread_ids + 4 + SRV_MAX_N_IO_THREADS); + srv_was_started = TRUE; srv_is_being_started = FALSE; From 877311779d8304bafc3aa24eee2e8af573d7f69f Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 23 Dec 2009 17:44:03 +0400 Subject: [PATCH 065/157] Bug#47649 crash during CALL procedure If first call of the procedure is failed on the open_table stage stmt_arena->state is set to EXECUTED state. On second call(if no errors on open_table stage) it leads to use of worng memory arena in find_field_in_view() function as thd->stmt_arena->is_stmt_prepare_or_first_sp_execute() returns FALSE for EXECUTED state. The item is created not in its own arena and it leads to crash on further calls of the procedure. The fix: change state of arena only if no errors on open_table stage happens. mysql-test/r/sp.result: test result mysql-test/t/sp.test: test case sql/sp_head.cc: If first call of the procedure is failed on the open_table stage stmt_arena->state is set to EXECUTED state. On second call(if no errors on open_table stage) it leads to use of worng memory arena in find_field_in_view() function as thd->stmt_arena->is_stmt_prepare_or_first_sp_execute() returns FALSE for EXECUTED state. The item is created not in its own arena and it leads to crash on further calls of the procedure. The fix: change state of arena only if no errors on open_table stage happens. --- mysql-test/r/sp.result | 16 ++++++++++++++++ mysql-test/t/sp.test | 19 +++++++++++++++++++ sql/sp_head.cc | 11 +++++++++-- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 83ad7545685..1e6227e7380 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6963,6 +6963,22 @@ CALL p1(); CALL p1(); DROP PROCEDURE p1; DROP TABLE t1; +CREATE TABLE t1 ( f1 integer, primary key (f1)); +CREATE TABLE t2 LIKE t1; +CREATE TEMPORARY TABLE t3 LIKE t1; +CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t3 AS A WHERE A.f1 IN ( SELECT f1 FROM t3 ) ; +END| +CALL p1; +ERROR HY000: Can't reopen table: 'A' +CREATE VIEW t3 AS SELECT f1 FROM t2 A WHERE A.f1 IN ( SELECT f1 FROM t2 ); +DROP TABLE t3; +CALL p1; +f1 +CALL p1; +f1 +DROP PROCEDURE p1; +DROP TABLE t1, t2; +DROP VIEW t3; # # Bug #46629: Item_in_subselect::val_int(): Assertion `0' # on subquery inside a SP diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 73ba62612b8..5cf050146dd 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -8242,6 +8242,25 @@ while ($tab_count) DROP PROCEDURE p1; DROP TABLE t1; +# +# Bug#47649 crash during CALL procedure +# +CREATE TABLE t1 ( f1 integer, primary key (f1)); +CREATE TABLE t2 LIKE t1; +CREATE TEMPORARY TABLE t3 LIKE t1; +delimiter |; +CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t3 AS A WHERE A.f1 IN ( SELECT f1 FROM t3 ) ; +END| +delimiter ;| +--error ER_CANT_REOPEN_TABLE +CALL p1; +CREATE VIEW t3 AS SELECT f1 FROM t2 A WHERE A.f1 IN ( SELECT f1 FROM t2 ); +DROP TABLE t3; +CALL p1; +CALL p1; +DROP PROCEDURE p1; +DROP TABLE t1, t2; +DROP VIEW t3; --echo # --echo # Bug #46629: Item_in_subselect::val_int(): Assertion `0' diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 51a731138ca..d74e195048f 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2773,8 +2773,15 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, m_lex->mark_as_requiring_prelocking(NULL); } thd->rollback_item_tree_changes(); - /* Update the state of the active arena. */ - thd->stmt_arena->state= Query_arena::EXECUTED; + /* + Update the state of the active arena if no errors on + open_tables stage. + */ + if (!res || !thd->is_error() || + (thd->main_da.sql_errno() != ER_CANT_REOPEN_TABLE && + thd->main_da.sql_errno() != ER_NO_SUCH_TABLE && + thd->main_da.sql_errno() != ER_UPDATE_TABLE_USED)) + thd->stmt_arena->state= Query_arena::EXECUTED; /* Merge here with the saved parent's values From 1f55f5b617d0df650161c58f7d0707abd4ca42e2 Mon Sep 17 00:00:00 2001 From: Satya B Date: Thu, 24 Dec 2009 12:02:29 +0530 Subject: [PATCH 066/157] Bug#49898 - Fix for bug#37408 introduces a linker error the declaration of THR_LOCK_myisam_mmap in mi_static is redundant as it accessible via the extern declaration in include/myisam.h myisam/mi_static.c: Bug#49898 - Fix for bug#37408 introduces a linker error Remove THR_LOCK_myisam_mmap declaration as it is redundant --- myisam/mi_static.c | 1 - 1 file changed, 1 deletion(-) diff --git a/myisam/mi_static.c b/myisam/mi_static.c index b6464e452d7..f75ede48828 100644 --- a/myisam/mi_static.c +++ b/myisam/mi_static.c @@ -41,7 +41,6 @@ my_off_t myisam_max_temp_length= MAX_FILE_SIZE; ulong myisam_bulk_insert_tree_size=8192*1024; ulong myisam_data_pointer_size=4; ulonglong myisam_mmap_size= SIZE_T_MAX, myisam_mmap_used= 0; -pthread_mutex_t THR_LOCK_myisam_mmap; static int always_valid(const char *filename __attribute__((unused))) { From a21a0b47ca46212a528c4402e4b473fe51437422 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 18 Dec 2009 14:00:30 +0200 Subject: [PATCH 067/157] Bug #31145: ALTER TABLE DROP COLUMN, ADD COLUMN crashes (linux) or freezes (win) the server The check for equality was assuming the field object is always created. If it's not it was de-referencing a NULL pointer. Fixed to use the data in the create object instead. --- mysql-test/r/alter_table.result | 7 +++++++ mysql-test/t/alter_table.test | 12 ++++++++++++ sql/field.cc | 3 +-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 06f4e7fbe8a..004e2031fb1 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -1338,4 +1338,11 @@ ALTER TABLE t1 CHANGE COLUMN f1 f1_no_real_change TIMESTAMP NULL DEFAULT NULL; affected rows: 0 info: Records: 0 Duplicates: 0 Warnings: 0 DROP TABLE t1; +# +# Bug #31145: ALTER TABLE DROP COLUMN, ADD COLUMN crashes (linux) +# or freezes (win) the server +# +CREATE TABLE t1 (a TEXT, id INT, b INT); +ALTER TABLE t1 DROP COLUMN a, ADD COLUMN c TEXT FIRST; +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index 5534aa0a234..4989a6c380c 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -1061,4 +1061,16 @@ ALTER TABLE t1 CHANGE COLUMN f1 f1_no_real_change TIMESTAMP NULL DEFAULT NULL; --disable_info DROP TABLE t1; + +--echo # +--echo # Bug #31145: ALTER TABLE DROP COLUMN, ADD COLUMN crashes (linux) +--echo # or freezes (win) the server +--echo # + +CREATE TABLE t1 (a TEXT, id INT, b INT); +ALTER TABLE t1 DROP COLUMN a, ADD COLUMN c TEXT FIRST; + +DROP TABLE t1; + + --echo End of 5.1 tests diff --git a/sql/field.cc b/sql/field.cc index 01ccc338782..d8db3fdbae4 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8282,8 +8282,7 @@ uint Field_blob::is_equal(Create_field *new_field) return ((new_field->sql_type == get_blob_type_from_length(max_data_length())) && new_field->charset == field_charset && - ((Field_blob *)new_field->field)->max_data_length() == - max_data_length()); + new_field->pack_length == pack_length()); } From 25be2b28d180e34afb8579311e431a6772f40809 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 18 Dec 2009 17:14:09 -0200 Subject: [PATCH 068/157] Bug#48983: Bad strmake calls (length one too long) MySQL 5.1 specific fixes. --- server-tools/instance-manager/instance_map.cc | 4 ++-- server-tools/instance-manager/options.cc | 4 ++-- server-tools/instance-manager/user_map.cc | 2 +- sql/sql_plugin.cc | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/server-tools/instance-manager/instance_map.cc b/server-tools/instance-manager/instance_map.cc index b137370b50a..a923c186b5d 100644 --- a/server-tools/instance-manager/instance_map.cc +++ b/server-tools/instance-manager/instance_map.cc @@ -117,13 +117,13 @@ static void parse_option(const char *option_str, while (*ptr == '-') ++ptr; - strmake(option_name_buf, ptr, MAX_OPTION_LEN + 1); + strmake(option_name_buf, ptr, MAX_OPTION_LEN); eq_pos= strchr(ptr, '='); if (eq_pos) { option_name_buf[eq_pos - ptr]= 0; - strmake(option_value_buf, eq_pos + 1, MAX_OPTION_LEN + 1); + strmake(option_value_buf, eq_pos + 1, MAX_OPTION_LEN); } else { diff --git a/server-tools/instance-manager/options.cc b/server-tools/instance-manager/options.cc index ebca593bb03..6e401bf3ffe 100644 --- a/server-tools/instance-manager/options.cc +++ b/server-tools/instance-manager/options.cc @@ -533,10 +533,10 @@ static int setup_windows_defaults() return 1; } - strmake(base_name, base_name_ptr, FN_REFLEN); + strmake(base_name, base_name_ptr, FN_REFLEN - 1); *base_name_ptr= 0; - strmake(im_name, base_name, FN_REFLEN); + strmake(im_name, base_name, FN_REFLEN - 1); ptr= strrchr(im_name, '.'); if (!ptr) diff --git a/server-tools/instance-manager/user_map.cc b/server-tools/instance-manager/user_map.cc index 49c35c16ca9..85e3f4a2cac 100644 --- a/server-tools/instance-manager/user_map.cc +++ b/server-tools/instance-manager/user_map.cc @@ -25,7 +25,7 @@ User::User(const LEX_STRING *user_name_arg, const char *password) { user_length= (uint8) (strmake(user, user_name_arg->str, - USERNAME_LENGTH + 1) - user); + USERNAME_LENGTH) - user); set_password(password); } diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index bafc601d142..9e35e392d2a 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -2084,7 +2084,7 @@ static int check_func_set(THD *thd, struct st_mysql_sys_var *var, &error, &error_len, ¬_used); if (error_len) { - strmake(buff, error, min(sizeof(buff), error_len)); + strmake(buff, error, min(sizeof(buff) - 1, error_len)); strvalue= buff; goto err; } From b66b3c1635dbda369b1466c7c7ff6103ae09ae66 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Fri, 18 Dec 2009 18:32:55 -0200 Subject: [PATCH 069/157] Bug#30331: Table_locks_waited shows inaccurate values Post-merge fix: wait for statement result before disconnecting. Otherwise, the statement might affect unrelated tests. mysql-test/t/lock_multi.test: Reap statement status. --- mysql-test/t/lock_multi.test | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index 47b5aa0292b..4df1a0f3478 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -626,9 +626,11 @@ let $wait_condition= --source include/wait_condition.inc let $tlwb= `show status like 'Table_locks_waited'`; unlock tables; +connection waiter; +--reap +connection default; drop table t1; disconnect waiter; -connection default; --disable_query_log eval SET @tlwa= SUBSTRING_INDEX('$tlwa', ' ', -1); eval SET @tlwb= SUBSTRING_INDEX('$tlwb', ' ', -1); From 00e6c3a89e1665c00b6553be28cf689996d6c58a Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Sun, 20 Dec 2009 19:02:15 +0100 Subject: [PATCH 070/157] Bug#43397 mysql headers redefine pthread_mutex_init unnecessarily Changing an instance of the define that was missed in the original commit due to the fact that it was misspelled. --- include/config-win.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/config-win.h b/include/config-win.h index af4915440b1..da9b1fc00c3 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -160,7 +160,7 @@ typedef uint rf_SetTimer; #define isnan(X) _isnan(X) #define finite(X) _finite(X) -#ifndef UNDEF_THREAD_HACK +#ifndef MYSQL_CLIENT_NO_THREADS #define THREAD #endif #define VOID_SIGHANDLER From 27aba1b56914694ed8e5615f67dc397680842341 Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Mon, 21 Dec 2009 14:14:45 +0800 Subject: [PATCH 071/157] Bug#47638 The rpl_killed_ddl test fails on Windows When the $diff_statement variable for diff_master_slave.inc was put in multiple lines, the rear part of the statement would be missing when being executed on Windows systems. Fixed the problem by always putting the value for $diff_statement in one line. mysql-test/suite/rpl/t/rpl_killed_ddl.test: putting the statement for $diff_statement variable in one line. --- mysql-test/suite/rpl/t/rpl_killed_ddl.test | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mysql-test/suite/rpl/t/rpl_killed_ddl.test b/mysql-test/suite/rpl/t/rpl_killed_ddl.test index 0f2fe5b60fb..61b882efcf3 100644 --- a/mysql-test/suite/rpl/t/rpl_killed_ddl.test +++ b/mysql-test/suite/rpl/t/rpl_killed_ddl.test @@ -158,8 +158,7 @@ source include/kill_query_and_diff_master_slave.inc; ######## EVENT ######## -let $diff_statement= SELECT event_name, event_body, execute_at - FROM information_schema.events where event_name like 'e%'; +let $diff_statement= SELECT event_name, event_body, execute_at FROM information_schema.events where event_name like 'e%'; send CREATE EVENT e2 ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY From 007d77afb9ea5fd7b7a369114f8963ab147fd2c5 Mon Sep 17 00:00:00 2001 From: Serge Kozlov Date: Mon, 21 Dec 2009 14:40:08 +0300 Subject: [PATCH 072/157] Bug#8693, Bug#45521. --- mysql-test/t/disabled.def | 2 -- 1 file changed, 2 deletions(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 062667c249e..61e1226c8e3 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -16,11 +16,9 @@ im_daemon_life_cycle : Bug#20294: Instance manager tests fail randomly im_options_set : Bug#20294: Instance manager tests fail randomly im_options_unset : Bug#20294: Instance manager tests fail randomly im_utils : Bug#20294: Instance manager tests fail randomly -rpl_log_pos : Bug#8693 Test 'rpl_log_pos' fails sometimes kill : Bug#29149 Test "kill" fails on Windows ps_7ndb : Bug#38315 "Cluster Failure" in ps_7ndb strict_autoinc_5ndb : Bug#35148 "Error '4009 Cluster Failure' in various tests on various platforms" -rpl_slave_skip : Bug#45521: rpl_slave_skip fails in pb2 loaddata_autocom_ndb : Bug#35148: Error '4009 Cluster Failure' in various tests on various platforms ndb_autodiscover3 : Bug#35148: Error '4009 Cluster Failure' in various tests on various platforms ndb_autodiscover : Bug#45972: ndb.ndb_autodiscover fails occasionally with pb2 From 7344b58c32c07df496c208dad5c1e11c304e8aac Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Tue, 22 Dec 2009 10:39:29 +0400 Subject: [PATCH 073/157] Fix for bug#49570: Assertion failed: !(order->used & map) on re-execution of prepared statement Problem: some (see eq_ref_table()) ORDER BY/GROUP BY optimization is called before each PS execution. However, we don't properly initialize its stucture every time before the call. Fix: properly initialize the sturture used. mysql-test/r/ps.result: Fix for bug#49570: Assertion failed: !(order->used & map) on re-execution of prepared statement - test result. mysql-test/t/ps.test: Fix for bug#49570: Assertion failed: !(order->used & map) on re-execution of prepared statement - test case. sql/sql_select.cc: Fix for bug#49570: Assertion failed: !(order->used & map) on re-execution of prepared statement - set order->used to 0 before each eq_ref_table() call, as the function relies on that. --- mysql-test/r/ps.result | 22 ++++++++++++++++++++++ mysql-test/t/ps.test | 16 ++++++++++++++++ sql/sql_select.cc | 1 + 3 files changed, 39 insertions(+) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 8a19b9b17e1..6e017ec7253 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1916,4 +1916,26 @@ execute stmt; deallocate prepare stmt; drop table t1,t2; # +# +# Bug #49570: Assertion failed: !(order->used & map) +# on re-execution of prepared statement +# +CREATE TABLE t1(a INT PRIMARY KEY); +INSERT INTO t1 VALUES(0), (1); +PREPARE stmt FROM +"SELECT 1 FROM t1 JOIN t1 t2 USING(a) GROUP BY t2.a, t1.a"; +EXECUTE stmt; +1 +1 +1 +EXECUTE stmt; +1 +1 +1 +EXECUTE stmt; +1 +1 +1 +DEALLOCATE PREPARE stmt; +DROP TABLE t1; End of 5.0 tests. diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 8f8e943913f..e207b0f154a 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1996,4 +1996,20 @@ deallocate prepare stmt; drop table t1,t2; --echo # + +--echo # +--echo # Bug #49570: Assertion failed: !(order->used & map) +--echo # on re-execution of prepared statement +--echo # +CREATE TABLE t1(a INT PRIMARY KEY); +INSERT INTO t1 VALUES(0), (1); +PREPARE stmt FROM + "SELECT 1 FROM t1 JOIN t1 t2 USING(a) GROUP BY t2.a, t1.a"; +EXECUTE stmt; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +DROP TABLE t1; + + --echo End of 5.0 tests. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d22a23a10d4..d8ec5eff5c1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6777,6 +6777,7 @@ static void update_depend_map(JOIN *join, ORDER *order) table_map depend_map; order->item[0]->update_used_tables(); order->depend_map=depend_map=order->item[0]->used_tables(); + order->used= 0; // Not item_sum(), RAND() and no reference to table outside of sub select if (!(order->depend_map & (OUTER_REF_TABLE_BIT | RAND_TABLE_BIT)) && !order->item[0]->with_sum_func) From 081bcb3b8bc861bc5609a4ce92c8eb3528ffc078 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 22 Dec 2009 13:52:23 +0400 Subject: [PATCH 074/157] Bug#47371 reference by same column name At the end of execution top level join execution we cleanup this join with true argument. It leads to underlying join cleanup(subquery) with true argument too and to tmp_table_param->field array cleanup which is required later. The problem is that Item_func_set_user_var does not set result_filed which leads to unnecessary repeated excution of subquery on final stage. The fix is to set result_field for Item_func_set_user_var. mysql-test/r/count_distinct.result: test result mysql-test/r/user_var.result: test result mysql-test/t/count_distinct.test: test case mysql-test/t/user_var.test: test case sql/item_func.cc: At the end of execution top level join execution we cleanup this join with true argument. It leads to underlying join cleanup(subquery) with true argument too and to tmp_table_param->field array cleanup which is required later. The problem is that Item_func_set_user_var does not set result_filed which leads to unnecessary repeated excution of subquery on final stage. The fix is to set result_field for Item_func_set_user_var. --- mysql-test/r/count_distinct.result | 20 ++++++++++++++++++++ mysql-test/r/user_var.result | 15 +++++++++++++++ mysql-test/t/count_distinct.test | 19 +++++++++++++++++++ mysql-test/t/user_var.test | 20 ++++++++++++++++++++ sql/item_func.cc | 2 +- 5 files changed, 75 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/count_distinct.result b/mysql-test/r/count_distinct.result index a21748359b9..804bc1f4788 100644 --- a/mysql-test/r/count_distinct.result +++ b/mysql-test/r/count_distinct.result @@ -40,6 +40,26 @@ select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join isbn city libname a 007 Berkeley Berkeley Public1 2 000 New York New York Public Libra 2 +select t2.isbn,city,@bar:=t1.libname,count(distinct t1.libname) as a +from t3 left join t1 on t3.libname=t1.libname left join t2 +on t3.isbn=t2.isbn group by city having count(distinct +t1.libname) > 1; +isbn city @bar:=t1.libname a +007 Berkeley Berkeley Public1 2 +000 New York New York Public Libra 2 +SELECT @bar; +@bar +Berkeley Public2 +select t2.isbn,city,concat(@bar:=t1.libname),count(distinct t1.libname) as a +from t3 left join t1 on t3.libname=t1.libname left join t2 +on t3.isbn=t2.isbn group by city having count(distinct +t1.libname) > 1; +isbn city concat(@bar:=t1.libname) a +007 Berkeley Berkeley Public1 2 +000 New York New York Public Libra 2 +SELECT @bar; +@bar +Berkeley Public2 drop table t1, t2, t3; create table t1 (f1 int); insert into t1 values (1); diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index bfa95d8f92b..8236dbe94ac 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -363,4 +363,19 @@ SELECT a, b FROM t1 WHERE a=2 AND b=3 GROUP BY a, b; a b 2 3 DROP TABLE t1; +CREATE TABLE t1 (f1 int(11) default NULL, f2 int(11) default NULL); +CREATE TABLE t2 (f1 int(11) default NULL, f2 int(11) default NULL, foo int(11)); +CREATE TABLE t3 (f1 int(11) default NULL, f2 int(11) default NULL); +INSERT INTO t1 VALUES(10, 10); +INSERT INTO t1 VALUES(10, 10); +INSERT INTO t2 VALUES(10, 10, 10); +INSERT INTO t2 VALUES(10, 10, 10); +INSERT INTO t3 VALUES(10, 10); +INSERT INTO t3 VALUES(10, 10); +SELECT MIN(t2.f1), +@bar:= (SELECT MIN(t3.f2) FROM t3 WHERE t3.f2 > foo) +FROM t1,t2 WHERE t1.f1 = t2.f1 ORDER BY t2.f1; +MIN(t2.f1) @bar:= (SELECT MIN(t3.f2) FROM t3 WHERE t3.f2 > foo) +10 NULL +DROP TABLE t1, t2, t3; End of 5.0 tests diff --git a/mysql-test/t/count_distinct.test b/mysql-test/t/count_distinct.test index e63bdabdb95..d0996689aeb 100644 --- a/mysql-test/t/count_distinct.test +++ b/mysql-test/t/count_distinct.test @@ -35,6 +35,25 @@ insert into t1 values ('NYC Lib','New York'); select t2.isbn,city,t1.libname,count(t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city,t1.libname; select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city having count(distinct t1.libname) > 1; select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city having count(distinct concat(t1.libname,'a')) > 1; + +select t2.isbn,city,@bar:=t1.libname,count(distinct t1.libname) as a + from t3 left join t1 on t3.libname=t1.libname left join t2 + on t3.isbn=t2.isbn group by city having count(distinct + t1.libname) > 1; +# +# Wrong result, see bug#49872 +# +SELECT @bar; + +select t2.isbn,city,concat(@bar:=t1.libname),count(distinct t1.libname) as a + from t3 left join t1 on t3.libname=t1.libname left join t2 + on t3.isbn=t2.isbn group by city having count(distinct + t1.libname) > 1; +# +# Wrong result, see bug#49872 +# +SELECT @bar; + drop table t1, t2, t3; # diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index d39b49a0e87..59a5238b35b 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -248,4 +248,24 @@ SELECT @a, @b; SELECT a, b FROM t1 WHERE a=2 AND b=3 GROUP BY a, b; DROP TABLE t1; +# +# Bug#47371: reference by same column name +# +CREATE TABLE t1 (f1 int(11) default NULL, f2 int(11) default NULL); +CREATE TABLE t2 (f1 int(11) default NULL, f2 int(11) default NULL, foo int(11)); +CREATE TABLE t3 (f1 int(11) default NULL, f2 int(11) default NULL); + +INSERT INTO t1 VALUES(10, 10); +INSERT INTO t1 VALUES(10, 10); +INSERT INTO t2 VALUES(10, 10, 10); +INSERT INTO t2 VALUES(10, 10, 10); +INSERT INTO t3 VALUES(10, 10); +INSERT INTO t3 VALUES(10, 10); + +SELECT MIN(t2.f1), +@bar:= (SELECT MIN(t3.f2) FROM t3 WHERE t3.f2 > foo) +FROM t1,t2 WHERE t1.f1 = t2.f1 ORDER BY t2.f1; + +DROP TABLE t1, t2, t3; + --echo End of 5.0 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index d6f315fda50..cb0d6bdbe5f 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -610,7 +610,7 @@ void Item_func::signal_divide_by_null() Item *Item_func::get_tmp_table_item(THD *thd) { - if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC) + if (!with_sum_func && !const_item()) return new Item_field(result_field); return copy_or_same(thd); } From 8f0f1d0ddb73283f60adb696f5b46b376aed327e Mon Sep 17 00:00:00 2001 From: Satya B Date: Tue, 22 Dec 2009 18:33:39 +0530 Subject: [PATCH 075/157] Removing rpl.rpl_trigger from experimental list as it is Fixed by BUG#46656 --- mysql-test/collections/default.experimental | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 2c2e9cab626..3894f2a4368 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -20,7 +20,6 @@ ndb.* # joro : NDB tests marked as experiment rpl.rpl_get_master_version_and_clock* # Bug #49191 2009-12-01 Daogang rpl_get_master_version_and_clock failed on PB2: COM_REGISTER_SLAVE failed rpl.rpl_innodb_bug28430* @solaris # Bug#46029 -rpl.rpl_trigger* # Bug#47810 2009-10-04 joro rpl.rpl_trigger.test fails with valgrind errors with the innodb plugin rpl_ndb.* # joro : NDB tests marked as experimental as agreed with bochklin rpl_ndb.rpl_ndb_log # Bug#38998 From 2d8869d248188c1bf393fc87d9f0e31adf691c2d Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 22 Dec 2009 17:52:15 +0200 Subject: [PATCH 076/157] Bug #49734: Crash on EXPLAIN EXTENDED UNION ... ORDER BY Several problems fixed : 1. Non constant expressions in UNION ... ORDER BY were not correctly cleaned up in st_select_lex_unit::cleanup() causing crashes in EXPLAIN EXTENDED because of fields quoted by these expressions pointing to the already freed temporary table used to calculate the UNION. Fixed by correctly cleaning up expressions of any depth. 2. Subqueries in the order by part of UNION ... ORDER BY ... caused a crash in EXPLAIN EXTENDED because of a transformation attempt made during EXPLAIN EXTENDED execution. Fixed by not doing the transformation when in EXPLAIN. 3. Fulltext functions caused crash when in the ORDER BY part of an un-parenthesized UNION that gets "promoted" to be valid for the whole union, e.g. SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY MATCHES (a) AGAINST ('abc' IN BOOLEAN MODE). This is a case that demonstrates a more general problem of parts of the query being moved to another level. When doing such transformation late in the optimization run when most of the flags about the contents of the query are already aggregated it's possible to "split" the flags so that they correctly reflect the new queries after the transformation. In specific the ST_SELECT_LEX::ftfunc_list is holding all the free text function for all the parts of the second SELECT in the UNION and we don't know what part of that is in the ORDER BY that we're to move to the UNION level and what part is about the other parts of the second SELECT. Fixed by throwing and error when such statements are about to be processed by adding a check for the presence of MATCH() inside the ORDER BY clause that's going to get promoted to UNION. To workaround this new limitation one must parenthesize the UNION SELECTs and provide a real global ORDER BY for the UNION outside of the parenthesis. --- mysql-test/r/fulltext_order_by.result | 6 +-- mysql-test/r/union.result | 63 +++++++++++++++++++++++++++ mysql-test/t/fulltext_order_by.test | 5 ++- mysql-test/t/union.test | 53 ++++++++++++++++++++++ sql/item.h | 17 ++++++++ sql/item_func.h | 5 +++ sql/sql_select.cc | 2 +- sql/sql_union.cc | 31 ++++++++++++- 8 files changed, 175 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/fulltext_order_by.result b/mysql-test/r/fulltext_order_by.result index bc466b5aba7..bd3e79ec5c2 100644 --- a/mysql-test/r/fulltext_order_by.result +++ b/mysql-test/r/fulltext_order_by.result @@ -126,7 +126,7 @@ group by a.text, b.id, b.betreff order by match(b.betreff) against ('+abc' in boolean mode) desc; -ERROR 42S22: Unknown column 'b.betreff' in 'order clause' +ERROR 42000: Incorrect usage/placement of 'MATCH()' select a.text, b.id, b.betreff from t2 a inner join t3 b on a.id = b.forum inner join @@ -142,7 +142,7 @@ where match(c.beitrag) against ('+abc' in boolean mode) order by match(b.betreff) against ('+abc' in boolean mode) desc; -ERROR 42S22: Unknown column 'b.betreff' in 'order clause' +ERROR 42000: Incorrect usage/placement of 'MATCH()' select a.text, b.id, b.betreff from t2 a inner join t3 b on a.id = b.forum inner join @@ -158,7 +158,7 @@ where match(c.beitrag) against ('+abc' in boolean mode) order by match(betreff) against ('+abc' in boolean mode) desc; -text id betreff +ERROR 42000: Incorrect usage/placement of 'MATCH()' (select b.id, b.betreff from t3 b) union (select b.id, b.betreff from t3 b) order by match(betreff) against ('+abc' in boolean mode) desc; diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 44a3812725a..dce32d2ced4 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -1588,3 +1588,66 @@ Warnings: Note 1003 select '0' AS `a` from `test`.`t1` union select '0' AS `a` from `test`.`t1` order by `a` DROP TABLE t1; End of 5.0 tests +# +# Bug #49734: Crash on EXPLAIN EXTENDED UNION ... ORDER BY +# +# +CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a)); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (1),(2); +# Should not crash +EXPLAIN EXTENDED +SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY a + 12; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 +2 UNION t1 ALL NULL NULL NULL NULL 2 100.00 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Using filesort +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` union select `test`.`t1`.`a` AS `a` from `test`.`t1` order by (`a` + 12) +# Should not crash +SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY a + 12; +a +1 +2 +# Should not crash +EXPLAIN EXTENDED +SELECT * FROM t1 UNION SELECT * FROM t1 +ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE); +ERROR 42000: Incorrect usage/placement of 'MATCH()' +# Should not crash +SELECT * FROM t1 UNION SELECT * FROM t1 +ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE); +ERROR 42000: Incorrect usage/placement of 'MATCH()' +# Should not crash +(SELECT * FROM t1) UNION (SELECT * FROM t1) +ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE); +a +1 +2 +# Should not crash +EXPLAIN EXTENDED +SELECT * FROM t1 UNION SELECT * FROM t1 +ORDER BY (SELECT a FROM t2 WHERE b = 12); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 +2 UNION t1 ALL NULL NULL NULL NULL 2 100.00 +3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where +NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Using filesort +Warnings: +Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #2 +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` union select `test`.`t1`.`a` AS `a` from `test`.`t1` order by (select `test`.`t1`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`b` = 12)) +# Should not crash +SELECT * FROM t1 UNION SELECT * FROM t1 +ORDER BY (SELECT a FROM t2 WHERE b = 12); +a +1 +2 +# Should not crash +SELECT * FROM t2 UNION SELECT * FROM t2 +ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)); +b +1 +2 +DROP TABLE t1,t2; +End of 5.1 tests diff --git a/mysql-test/t/fulltext_order_by.test b/mysql-test/t/fulltext_order_by.test index 074aefbf943..814cd4a5954 100644 --- a/mysql-test/t/fulltext_order_by.test +++ b/mysql-test/t/fulltext_order_by.test @@ -80,7 +80,7 @@ CREATE TABLE t3 ( FULLTEXT KEY betreff (betreff) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=996 ; ---error 1054 +--error ER_CANT_USE_OPTION_HERE select a.text, b.id, b.betreff from t2 a inner join t3 b on a.id = b.forum inner join @@ -100,7 +100,7 @@ group by order by match(b.betreff) against ('+abc' in boolean mode) desc; ---error 1054 +--error ER_CANT_USE_OPTION_HERE select a.text, b.id, b.betreff from t2 a inner join t3 b on a.id = b.forum inner join @@ -117,6 +117,7 @@ where order by match(b.betreff) against ('+abc' in boolean mode) desc; +--error ER_CANT_USE_OPTION_HERE select a.text, b.id, b.betreff from t2 a inner join t3 b on a.id = b.forum inner join diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index ec169838d59..91fc9546bbe 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -1102,3 +1102,56 @@ DROP TABLE t1; --echo End of 5.0 tests + + +--echo # +--echo # Bug #49734: Crash on EXPLAIN EXTENDED UNION ... ORDER BY +--echo # +--echo # + +CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a)); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (1),(2); + +--echo # Should not crash +EXPLAIN EXTENDED +SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY a + 12; + +--echo # Should not crash +SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY a + 12; + + +--echo # Should not crash +--error ER_CANT_USE_OPTION_HERE +EXPLAIN EXTENDED +SELECT * FROM t1 UNION SELECT * FROM t1 + ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE); + +--echo # Should not crash +--error ER_CANT_USE_OPTION_HERE +SELECT * FROM t1 UNION SELECT * FROM t1 + ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE); + +--echo # Should not crash +(SELECT * FROM t1) UNION (SELECT * FROM t1) + ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE); + + +--echo # Should not crash +EXPLAIN EXTENDED +SELECT * FROM t1 UNION SELECT * FROM t1 + ORDER BY (SELECT a FROM t2 WHERE b = 12); + +--echo # Should not crash +SELECT * FROM t1 UNION SELECT * FROM t1 + ORDER BY (SELECT a FROM t2 WHERE b = 12); + +--echo # Should not crash +SELECT * FROM t2 UNION SELECT * FROM t2 + ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)); + +DROP TABLE t1,t2; + + +--echo End of 5.1 tests diff --git a/sql/item.h b/sql/item.h index b97808ac87f..8f0e5874f3f 100644 --- a/sql/item.h +++ b/sql/item.h @@ -967,6 +967,23 @@ public: return FALSE; } + /** + Find a function of a given type + + @param arg the function type to search (enum Item_func::Functype) + @return + @retval TRUE the function type we're searching for is found + @retval FALSE the function type wasn't found + + @description + This function can be used (together with Item::walk()) to find functions + in an item tree fragment. + */ + virtual bool find_function_processor (uchar *arg) + { + return FALSE; + } + /* For SP local variable returns pointer to Item representing its current value and pointer to current Item otherwise. diff --git a/sql/item_func.h b/sql/item_func.h index 259316b0c41..71168c64e4b 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -212,6 +212,11 @@ public: { return has_timestamp_args(); } + + virtual bool find_function_processor (uchar *arg) + { + return functype() == *(Functype *) arg; + } }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6383fe63012..d50bb888850 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -519,7 +519,7 @@ JOIN::prepare(Item ***rref_pointer_array, thd->lex->allow_sum_func= save_allow_sum_func; } - if (!thd->lex->view_prepare_mode) + if (!thd->lex->view_prepare_mode && !(select_options & SELECT_DESCRIBE)) { Item_subselect *subselect; /* Is it subselect? */ diff --git a/sql/sql_union.cc b/sql/sql_union.cc index cbf94ad7181..1760670f9c8 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -335,6 +335,35 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, } } + /* + Disable the usage of fulltext searches in the last union branch. + This is a temporary 5.x limitation because of the way the fulltext + search functions are handled by the optimizer. + This is manifestation of the more general problems of "taking away" + parts of a SELECT statement post-fix_fields(). This is generally not + doable since various flags are collected in various places (e.g. + SELECT_LEX) that carry information about the presence of certain + expressions or constructs in the parts of the query. + When part of the query is taken away it's not clear how to "divide" + the meaning of these accumulated flags and what to carry over to the + recipient query (SELECT_LEX). + */ + if (global_parameters->ftfunc_list->elements && + global_parameters->order_list.elements && + global_parameters != fake_select_lex) + { + ORDER *ord; + Item_func::Functype ft= Item_func::FT_FUNC; + for (ord= (ORDER*)global_parameters->order_list.first; ord; ord= ord->next) + if ((*ord->item)->walk (&Item::find_function_processor, FALSE, + (uchar *) &ft)) + { + my_error (ER_CANT_USE_OPTION_HERE, MYF(0), "MATCH()"); + goto err; + } + } + + create_options= (first_sl->options | thd_arg->options | TMP_TABLE_ALL_COLUMNS); /* @@ -669,7 +698,7 @@ bool st_select_lex_unit::cleanup() { ORDER *ord; for (ord= (ORDER*)global_parameters->order_list.first; ord; ord= ord->next) - (*ord->item)->cleanup(); + (*ord->item)->walk (&Item::cleanup_processor, 0, 0); } } From 28e64daf2ddccbeb754d4204219463eddd44012f Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Tue, 22 Dec 2009 18:59:37 +0100 Subject: [PATCH 077/157] Bug#49742: Partition Pruning not working correctly for RANGE Problem was when calculating the range of partitions for pruning. Solution was to get the calculation correct. I also simplified it a bit for easier understanding. mysql-test/r/partition_pruning.result: Bug#49742: Partition Pruning not working correctly for RANGE Added results. mysql-test/t/partition_pruning.test: Bug#49742: Partition Pruning not working correctly for RANGE Added tests to prevent regressions. sql/sql_partition.cc: Bug#49742: Partition Pruning not working correctly for RANGE Simplified calculation for partition id for ranges. Easier to get right and understand. Added comments. --- mysql-test/r/partition_pruning.result | 612 +++++++++++++++++++++++++- mysql-test/t/partition_pruning.test | 160 +++++++ sql/sql_partition.cc | 47 +- 3 files changed, 793 insertions(+), 26 deletions(-) diff --git a/mysql-test/r/partition_pruning.result b/mysql-test/r/partition_pruning.result index 3128c57b2cf..cf0474a3f6b 100644 --- a/mysql-test/r/partition_pruning.result +++ b/mysql-test/r/partition_pruning.result @@ -1,4 +1,614 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +# +# Bug#49742: Partition Pruning not working correctly for RANGE +# +CREATE TABLE t1 (a INT PRIMARY KEY) +PARTITION BY RANGE (a) ( +PARTITION p0 VALUES LESS THAN (1), +PARTITION p1 VALUES LESS THAN (2), +PARTITION p2 VALUES LESS THAN (3), +PARTITION p3 VALUES LESS THAN (4), +PARTITION p4 VALUES LESS THAN (5), +PARTITION p5 VALUES LESS THAN (6), +PARTITION max VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (-1),(0),(1),(2),(3),(4),(5),(6),(7),(8); +SELECT * FROM t1 WHERE a < 1; +a +-1 +0 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 1; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index +SELECT * FROM t1 WHERE a < 2; +a +-1 +0 +1 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 2; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1 index PRIMARY PRIMARY 4 NULL 3 Using where; Using index +SELECT * FROM t1 WHERE a < 3; +a +-1 +0 +1 +2 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 3; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index +SELECT * FROM t1 WHERE a < 4; +a +-1 +0 +1 +2 +3 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 4; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2,p3 index PRIMARY PRIMARY 4 NULL 5 Using where; Using index +SELECT * FROM t1 WHERE a < 5; +a +-1 +0 +1 +2 +3 +4 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 5; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2,p3,p4 index PRIMARY PRIMARY 4 NULL 6 Using where; Using index +SELECT * FROM t1 WHERE a < 6; +a +-1 +0 +1 +2 +3 +4 +5 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 6; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2,p3,p4,p5 index PRIMARY PRIMARY 4 NULL 7 Using where; Using index +SELECT * FROM t1 WHERE a < 7; +a +-1 +0 +1 +2 +3 +4 +5 +6 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 7; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL 9 Using where; Using index +SELECT * FROM t1 WHERE a <= 1; +a +-1 +0 +1 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +SELECT * FROM t1 WHERE a <= 2; +a +-1 +0 +1 +2 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 2; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +SELECT * FROM t1 WHERE a <= 3; +a +-1 +0 +1 +2 +3 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 3; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2,p3 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +SELECT * FROM t1 WHERE a <= 4; +a +-1 +0 +1 +2 +3 +4 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 4; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2,p3,p4 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +SELECT * FROM t1 WHERE a <= 5; +a +-1 +0 +1 +2 +3 +4 +5 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 5; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2,p3,p4,p5 index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +SELECT * FROM t1 WHERE a <= 6; +a +-1 +0 +1 +2 +3 +4 +5 +6 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 6; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL 9 Using where; Using index +SELECT * FROM t1 WHERE a <= 7; +a +-1 +0 +1 +2 +3 +4 +5 +6 +7 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 7; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2,p3,p4,p5,max range PRIMARY PRIMARY 4 NULL 9 Using where; Using index +SELECT * FROM t1 WHERE a = 1; +a +1 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 1; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p1 system PRIMARY NULL NULL NULL 1 +SELECT * FROM t1 WHERE a = 2; +a +2 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 2; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2 system PRIMARY NULL NULL NULL 1 +SELECT * FROM t1 WHERE a = 3; +a +3 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 3; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p3 system PRIMARY NULL NULL NULL 1 +SELECT * FROM t1 WHERE a = 4; +a +4 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 4; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p4 system PRIMARY NULL NULL NULL 1 +SELECT * FROM t1 WHERE a = 5; +a +5 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 5; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p5 system PRIMARY NULL NULL NULL 1 +SELECT * FROM t1 WHERE a = 6; +a +6 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 6; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 max const PRIMARY PRIMARY 4 const 1 Using index +SELECT * FROM t1 WHERE a = 7; +a +7 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 7; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 max const PRIMARY PRIMARY 4 const 1 Using index +SELECT * FROM t1 WHERE a >= 1; +a +1 +2 +3 +4 +5 +6 +7 +8 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 1; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p1,p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +SELECT * FROM t1 WHERE a >= 2; +a +2 +3 +4 +5 +6 +7 +8 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 2; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +SELECT * FROM t1 WHERE a >= 3; +a +3 +4 +5 +6 +7 +8 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 3; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +SELECT * FROM t1 WHERE a >= 4; +a +4 +5 +6 +7 +8 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 4; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +SELECT * FROM t1 WHERE a >= 5; +a +5 +6 +7 +8 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 5; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +SELECT * FROM t1 WHERE a >= 6; +a +6 +7 +8 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 6; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +SELECT * FROM t1 WHERE a >= 7; +a +7 +8 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 7; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 max range PRIMARY PRIMARY 4 NULL 2 Using where; Using index +SELECT * FROM t1 WHERE a > 1; +a +2 +3 +4 +5 +6 +7 +8 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 1; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2,p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +SELECT * FROM t1 WHERE a > 2; +a +3 +4 +5 +6 +7 +8 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 2; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p3,p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +SELECT * FROM t1 WHERE a > 3; +a +4 +5 +6 +7 +8 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 3; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p4,p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +SELECT * FROM t1 WHERE a > 4; +a +5 +6 +7 +8 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 4; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p5,max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +SELECT * FROM t1 WHERE a > 5; +a +6 +7 +8 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 5; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 10 Using where; Using index +SELECT * FROM t1 WHERE a > 6; +a +7 +8 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 6; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 max range PRIMARY PRIMARY 4 NULL 2 Using where; Using index +SELECT * FROM t1 WHERE a > 7; +a +8 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 7; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 max range PRIMARY PRIMARY 4 NULL 2 Using where; Using index +DROP TABLE t1; +CREATE TABLE t1 (a INT PRIMARY KEY) +PARTITION BY RANGE (a) ( +PARTITION p0 VALUES LESS THAN (1), +PARTITION p1 VALUES LESS THAN (2), +PARTITION p2 VALUES LESS THAN (3), +PARTITION p3 VALUES LESS THAN (4), +PARTITION p4 VALUES LESS THAN (5), +PARTITION max VALUES LESS THAN MAXVALUE); +INSERT INTO t1 VALUES (-1),(0),(1),(2),(3),(4),(5),(6),(7); +SELECT * FROM t1 WHERE a < 1; +a +-1 +0 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 1; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index +SELECT * FROM t1 WHERE a < 2; +a +-1 +0 +1 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 2; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1 index PRIMARY PRIMARY 4 NULL 3 Using where; Using index +SELECT * FROM t1 WHERE a < 3; +a +-1 +0 +1 +2 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 3; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index +SELECT * FROM t1 WHERE a < 4; +a +-1 +0 +1 +2 +3 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 4; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2,p3 index PRIMARY PRIMARY 4 NULL 5 Using where; Using index +SELECT * FROM t1 WHERE a < 5; +a +-1 +0 +1 +2 +3 +4 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 5; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2,p3,p4 index PRIMARY PRIMARY 4 NULL 6 Using where; Using index +SELECT * FROM t1 WHERE a < 6; +a +-1 +0 +1 +2 +3 +4 +5 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 6; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL 8 Using where; Using index +SELECT * FROM t1 WHERE a <= 1; +a +-1 +0 +1 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1 index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +SELECT * FROM t1 WHERE a <= 2; +a +-1 +0 +1 +2 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 2; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2 index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +SELECT * FROM t1 WHERE a <= 3; +a +-1 +0 +1 +2 +3 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 3; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2,p3 index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +SELECT * FROM t1 WHERE a <= 4; +a +-1 +0 +1 +2 +3 +4 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 4; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2,p3,p4 index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +SELECT * FROM t1 WHERE a <= 5; +a +-1 +0 +1 +2 +3 +4 +5 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 5; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL 8 Using where; Using index +SELECT * FROM t1 WHERE a <= 6; +a +-1 +0 +1 +2 +3 +4 +5 +6 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 6; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p0,p1,p2,p3,p4,max range PRIMARY PRIMARY 4 NULL 8 Using where; Using index +SELECT * FROM t1 WHERE a = 1; +a +1 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 1; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p1 system PRIMARY NULL NULL NULL 1 +SELECT * FROM t1 WHERE a = 2; +a +2 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 2; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2 system PRIMARY NULL NULL NULL 1 +SELECT * FROM t1 WHERE a = 3; +a +3 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 3; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p3 system PRIMARY NULL NULL NULL 1 +SELECT * FROM t1 WHERE a = 4; +a +4 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 4; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p4 system PRIMARY NULL NULL NULL 1 +SELECT * FROM t1 WHERE a = 5; +a +5 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 5; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 max const PRIMARY PRIMARY 4 const 1 Using index +SELECT * FROM t1 WHERE a = 6; +a +6 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 6; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 max const PRIMARY PRIMARY 4 const 1 Using index +SELECT * FROM t1 WHERE a >= 1; +a +1 +2 +3 +4 +5 +6 +7 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 1; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p1,p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +SELECT * FROM t1 WHERE a >= 2; +a +2 +3 +4 +5 +6 +7 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 2; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +SELECT * FROM t1 WHERE a >= 3; +a +3 +4 +5 +6 +7 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 3; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +SELECT * FROM t1 WHERE a >= 4; +a +4 +5 +6 +7 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 4; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +SELECT * FROM t1 WHERE a >= 5; +a +5 +6 +7 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 5; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +SELECT * FROM t1 WHERE a >= 6; +a +6 +7 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 6; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 max range PRIMARY PRIMARY 4 NULL 2 Using where; Using index +SELECT * FROM t1 WHERE a > 1; +a +2 +3 +4 +5 +6 +7 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 1; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p2,p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +SELECT * FROM t1 WHERE a > 2; +a +3 +4 +5 +6 +7 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 2; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p3,p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +SELECT * FROM t1 WHERE a > 3; +a +4 +5 +6 +7 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 3; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 p4,max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +SELECT * FROM t1 WHERE a > 4; +a +5 +6 +7 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 4; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 max index PRIMARY PRIMARY 4 NULL 9 Using where; Using index +SELECT * FROM t1 WHERE a > 5; +a +6 +7 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 5; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 max range PRIMARY PRIMARY 4 NULL 2 Using where; Using index +SELECT * FROM t1 WHERE a > 6; +a +7 +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 6; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 max range PRIMARY PRIMARY 4 NULL 2 Using where; Using index +DROP TABLE t1; # test of RANGE and index CREATE TABLE t1 (a DATE, KEY(a)) PARTITION BY RANGE (TO_DAYS(a)) @@ -1816,7 +2426,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t2 p0,p4 ALL NULL NULL NULL NULL 910 Using where explain partitions select * from t2 where (a > 100 AND a < 600); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p0,p1,p2,p3 ALL NULL NULL NULL NULL 910 Using where +1 SIMPLE t2 p0,p1,p2 ALL NULL NULL NULL NULL 910 Using where explain partitions select * from t2 where b = 4; id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t2 p0,p1,p2,p3,p4 ref b b 5 const 76 Using where diff --git a/mysql-test/t/partition_pruning.test b/mysql-test/t/partition_pruning.test index 11e65be45fc..315b8393d93 100644 --- a/mysql-test/t/partition_pruning.test +++ b/mysql-test/t/partition_pruning.test @@ -8,6 +8,166 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; --enable_warnings +--echo # +--echo # Bug#49742: Partition Pruning not working correctly for RANGE +--echo # +CREATE TABLE t1 (a INT PRIMARY KEY) +PARTITION BY RANGE (a) ( +PARTITION p0 VALUES LESS THAN (1), +PARTITION p1 VALUES LESS THAN (2), +PARTITION p2 VALUES LESS THAN (3), +PARTITION p3 VALUES LESS THAN (4), +PARTITION p4 VALUES LESS THAN (5), +PARTITION p5 VALUES LESS THAN (6), +PARTITION max VALUES LESS THAN MAXVALUE); + +INSERT INTO t1 VALUES (-1),(0),(1),(2),(3),(4),(5),(6),(7),(8); + +SELECT * FROM t1 WHERE a < 1; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 1; +SELECT * FROM t1 WHERE a < 2; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 2; +SELECT * FROM t1 WHERE a < 3; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 3; +SELECT * FROM t1 WHERE a < 4; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 4; +SELECT * FROM t1 WHERE a < 5; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 5; +SELECT * FROM t1 WHERE a < 6; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 6; +SELECT * FROM t1 WHERE a < 7; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 7; +SELECT * FROM t1 WHERE a <= 1; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1; +SELECT * FROM t1 WHERE a <= 2; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 2; +SELECT * FROM t1 WHERE a <= 3; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 3; +SELECT * FROM t1 WHERE a <= 4; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 4; +SELECT * FROM t1 WHERE a <= 5; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 5; +SELECT * FROM t1 WHERE a <= 6; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 6; +SELECT * FROM t1 WHERE a <= 7; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 7; +SELECT * FROM t1 WHERE a = 1; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 1; +SELECT * FROM t1 WHERE a = 2; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 2; +SELECT * FROM t1 WHERE a = 3; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 3; +SELECT * FROM t1 WHERE a = 4; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 4; +SELECT * FROM t1 WHERE a = 5; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 5; +SELECT * FROM t1 WHERE a = 6; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 6; +SELECT * FROM t1 WHERE a = 7; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 7; +SELECT * FROM t1 WHERE a >= 1; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 1; +SELECT * FROM t1 WHERE a >= 2; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 2; +SELECT * FROM t1 WHERE a >= 3; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 3; +SELECT * FROM t1 WHERE a >= 4; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 4; +SELECT * FROM t1 WHERE a >= 5; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 5; +SELECT * FROM t1 WHERE a >= 6; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 6; +SELECT * FROM t1 WHERE a >= 7; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 7; +SELECT * FROM t1 WHERE a > 1; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 1; +SELECT * FROM t1 WHERE a > 2; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 2; +SELECT * FROM t1 WHERE a > 3; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 3; +SELECT * FROM t1 WHERE a > 4; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 4; +SELECT * FROM t1 WHERE a > 5; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 5; +SELECT * FROM t1 WHERE a > 6; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 6; +SELECT * FROM t1 WHERE a > 7; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 7; +DROP TABLE t1; + +CREATE TABLE t1 (a INT PRIMARY KEY) +PARTITION BY RANGE (a) ( +PARTITION p0 VALUES LESS THAN (1), +PARTITION p1 VALUES LESS THAN (2), +PARTITION p2 VALUES LESS THAN (3), +PARTITION p3 VALUES LESS THAN (4), +PARTITION p4 VALUES LESS THAN (5), +PARTITION max VALUES LESS THAN MAXVALUE); + +INSERT INTO t1 VALUES (-1),(0),(1),(2),(3),(4),(5),(6),(7); + +SELECT * FROM t1 WHERE a < 1; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 1; +SELECT * FROM t1 WHERE a < 2; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 2; +SELECT * FROM t1 WHERE a < 3; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 3; +SELECT * FROM t1 WHERE a < 4; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 4; +SELECT * FROM t1 WHERE a < 5; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 5; +SELECT * FROM t1 WHERE a < 6; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a < 6; +SELECT * FROM t1 WHERE a <= 1; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 1; +SELECT * FROM t1 WHERE a <= 2; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 2; +SELECT * FROM t1 WHERE a <= 3; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 3; +SELECT * FROM t1 WHERE a <= 4; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 4; +SELECT * FROM t1 WHERE a <= 5; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 5; +SELECT * FROM t1 WHERE a <= 6; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a <= 6; +SELECT * FROM t1 WHERE a = 1; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 1; +SELECT * FROM t1 WHERE a = 2; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 2; +SELECT * FROM t1 WHERE a = 3; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 3; +SELECT * FROM t1 WHERE a = 4; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 4; +SELECT * FROM t1 WHERE a = 5; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 5; +SELECT * FROM t1 WHERE a = 6; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a = 6; +SELECT * FROM t1 WHERE a >= 1; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 1; +SELECT * FROM t1 WHERE a >= 2; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 2; +SELECT * FROM t1 WHERE a >= 3; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 3; +SELECT * FROM t1 WHERE a >= 4; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 4; +SELECT * FROM t1 WHERE a >= 5; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 5; +SELECT * FROM t1 WHERE a >= 6; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a >= 6; +SELECT * FROM t1 WHERE a > 1; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 1; +SELECT * FROM t1 WHERE a > 2; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 2; +SELECT * FROM t1 WHERE a > 3; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 3; +SELECT * FROM t1 WHERE a > 4; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 4; +SELECT * FROM t1 WHERE a > 5; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 5; +SELECT * FROM t1 WHERE a > 6; +EXPLAIN PARTITIONS SELECT * FROM t1 WHERE a > 6; +DROP TABLE t1; + # # Bug#20577: Partitions: use of to_days() function leads to selection failures # diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index e0697f563ea..2f22432c416 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -2878,16 +2878,13 @@ int get_partition_id_range(partition_info *part_info, part_func_value-= 0x8000000000000000ULL; while (max_part_id > min_part_id) { - loc_part_id= (max_part_id + min_part_id + 1) >> 1; + loc_part_id= (max_part_id + min_part_id) / 2; if (range_array[loc_part_id] <= part_func_value) min_part_id= loc_part_id + 1; else - max_part_id= loc_part_id - 1; + max_part_id= loc_part_id; } loc_part_id= max_part_id; - if (part_func_value >= range_array[loc_part_id]) - if (loc_part_id != max_partition) - loc_part_id++; *part_id= (uint32)loc_part_id; if (loc_part_id == max_partition && part_func_value >= range_array[loc_part_id] && @@ -2961,6 +2958,7 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info, bool include_endpoint) { longlong *range_array= part_info->range_int_array; + longlong part_end_val; uint max_partition= part_info->no_parts - 1; uint min_part_id= 0, max_part_id= max_partition, loc_part_id; /* Get the partitioning function value for the endpoint */ @@ -2994,46 +2992,45 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info, } } - if (unsigned_flag) part_func_value-= 0x8000000000000000ULL; if (left_endpoint && !include_endpoint) part_func_value++; + + /* + Search for the partition containing part_func_value + (including the right endpoint). + */ while (max_part_id > min_part_id) { - loc_part_id= (max_part_id + min_part_id + 1) >> 1; - if (range_array[loc_part_id] <= part_func_value) + loc_part_id= (max_part_id + min_part_id) / 2; + if (range_array[loc_part_id] < part_func_value) min_part_id= loc_part_id + 1; else - max_part_id= loc_part_id - 1; + max_part_id= loc_part_id; } loc_part_id= max_part_id; - if (loc_part_id < max_partition && - part_func_value >= range_array[loc_part_id+1]) - { - loc_part_id++; - } + + /* Adjust for endpoints */ + part_end_val= range_array[loc_part_id]; if (left_endpoint) { - longlong bound= range_array[loc_part_id]; /* In case of PARTITION p VALUES LESS THAN MAXVALUE the maximum value is in the current partition. */ - if (part_func_value > bound || - (part_func_value == bound && - (!part_info->defined_max_value || loc_part_id < max_partition))) + if (part_func_value == part_end_val && + (loc_part_id < max_partition || !part_info->defined_max_value)) loc_part_id++; } else { - if (loc_part_id < max_partition) - { - if (part_func_value == range_array[loc_part_id]) - loc_part_id += test(include_endpoint); - else if (part_func_value > range_array[loc_part_id]) - loc_part_id++; - } + /* if 'WHERE <= X' and partition is LESS THAN (X) include next partition */ + if (include_endpoint && loc_part_id < max_partition && + part_func_value == part_end_val) + loc_part_id++; + + /* Right endpoint, set end after correct partition */ loc_part_id++; } DBUG_RETURN(loc_part_id); From 5ba1dd04748561ae2a9942f9f228c8c6a52de72b Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 18 Jan 2010 17:50:46 +0200 Subject: [PATCH 078/157] Bug #45989 take 2 : memory leak after explain encounters an error in the query. Fixes a leak after materializing a GROUP BY subquery to a temp table when the subquery has a blob column in the SELECT list. Fixed by correctly destructing temporary buffers after doing the conversion. --- mysql-test/r/subselect.result | 12 ++++++++++++ mysql-test/t/subselect.test | 17 +++++++++++++++++ sql/sql_select.cc | 2 ++ 3 files changed, 31 insertions(+) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index f446d8feec3..99d1f18b010 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4602,4 +4602,16 @@ SELECT 1 FROM t1 GROUP BY 1 1 DROP TABLE t1; +# +# Bug #45989 take 2 : memory leak after explain encounters an +# error in the query +# +CREATE TABLE t1(a LONGTEXT); +INSERT INTO t1 VALUES (repeat('a',@@global.max_allowed_packet)); +INSERT INTO t1 VALUES (repeat('b',@@global.max_allowed_packet)); +EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1, +(SELECT DISTINCTROW a AS away FROM t1 GROUP BY a WITH ROLLUP) AS d1 +WHERE t1.a = d1.a; +ERROR 42S22: Unknown column 'd1.a' in 'where clause' +DROP TABLE t1; End of 5.1 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index a4314c45cba..eca86de1e82 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3585,4 +3585,21 @@ SELECT 1 FROM t1 GROUP BY (SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1); DROP TABLE t1; +--echo # +--echo # Bug #45989 take 2 : memory leak after explain encounters an +--echo # error in the query +--echo # + +CREATE TABLE t1(a LONGTEXT); +INSERT INTO t1 VALUES (repeat('a',@@global.max_allowed_packet)); +INSERT INTO t1 VALUES (repeat('b',@@global.max_allowed_packet)); + +--error ER_BAD_FIELD_ERROR +EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1, +(SELECT DISTINCTROW a AS away FROM t1 GROUP BY a WITH ROLLUP) AS d1 +WHERE t1.a = d1.a; + +DROP TABLE t1; + + --echo End of 5.1 tests. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 644f0072b7b..24876ffec14 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5824,6 +5824,8 @@ JOIN::make_simple_join(JOIN *parent, TABLE *tmp_table) const_table_map= 0; tmp_table_param.field_count= tmp_table_param.sum_func_count= tmp_table_param.func_count= 0; + if (tmp_table_param.copy_field) + delete [] tmp_table_param.copy_field; tmp_table_param.copy_field= tmp_table_param.copy_field_end=0; first_record= sort_and_group=0; send_records= (ha_rows) 0; From eab2be0aeed0459c505578a716f8b0ae88a8f365 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Mon, 18 Jan 2010 17:49:18 +0100 Subject: [PATCH 079/157] Bug#47343: InnoDB fails to clean-up after lock wait timeout on REORGANIZE PARTITION There were several problems which lead to this this, all related to bad error handling. 1) There was several bugs preventing the ddl-log to be used for cleaning up created files on error. 2) The error handling after the copy partition rows did not close and unlock the tables, resulting in deletion of partitions which were in use, which lead InnoDB to put the partition to drop in a background queue. sql/ha_partition.cc: Bug#47343: InnoDB fails to clean-up after lock wait timeout on REORGANIZE PARTITION Better error handling, if partition has been created/opened/locked then make sure it is unlocked and closed before returning error. The delete of the newly created partition is handled by the ddl-log. sql/sql_parse.cc: Bug#47343: InnoDB fails to clean-up after lock wait timeout on REORGANIZE PARTITION Fix a bug found when experimenting, thd could really be NULL here, as mentioned in the function header. sql/sql_partition.cc: Bug#47343: InnoDB fails to clean-up after lock wait timeout on REORGANIZE PARTITION Used the correct .frm shadow name to put into the ddl-log. Really use the ddl-log to handle errors. sql/sql_table.cc: Bug#47343: InnoDB fails to clean-up after lock wait timeout on REORGANIZE PARTITION Fixes of the ddl-log when used as error recovery (no crash). When executing an entry from memory (not read from disk) the name_len was not set correctly. --- mysql-test/r/partition_innodb.result | 44 ++++++++++++++++ mysql-test/t/partition_innodb-master.opt | 1 + mysql-test/t/partition_innodb.test | 45 ++++++++++++++++- sql/ha_partition.cc | 64 +++++++++++++++++------- sql/sql_parse.cc | 2 +- sql/sql_partition.cc | 8 ++- sql/sql_table.cc | 23 +++++++-- 7 files changed, 158 insertions(+), 29 deletions(-) create mode 100644 mysql-test/t/partition_innodb-master.opt diff --git a/mysql-test/r/partition_innodb.result b/mysql-test/r/partition_innodb.result index b8cfa25349d..f2f6ef138ff 100644 --- a/mysql-test/r/partition_innodb.result +++ b/mysql-test/r/partition_innodb.result @@ -274,3 +274,47 @@ CREATE TABLE t1 (a INT) ENGINE=InnoDB PARTITION BY list(a) (PARTITION p1 VALUES IN (1)); CREATE INDEX i1 ON t1 (a); DROP TABLE t1; +# +# Bug#47343: InnoDB fails to clean-up after lock wait timeout on +# REORGANIZE PARTITION +# +CREATE TABLE t1 ( +a INT, +b DATE NOT NULL, +PRIMARY KEY (a, b) +) ENGINE=InnoDB +PARTITION BY RANGE (a) ( +PARTITION pMAX VALUES LESS THAN MAXVALUE +) ; +INSERT INTO t1 VALUES (1, '2001-01-01'), (2, '2002-02-02'), (3, '2003-03-03'); +START TRANSACTION; +SELECT * FROM t1 FOR UPDATE; +a b +1 2001-01-01 +2 2002-02-02 +3 2003-03-03 +# Connection con1 +ALTER TABLE t1 REORGANIZE PARTITION pMAX INTO +(PARTITION p3 VALUES LESS THAN (3), +PARTITION pMAX VALUES LESS THAN MAXVALUE); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SHOW WARNINGS; +Level Code Message +Error 1205 Lock wait timeout exceeded; try restarting transaction +ALTER TABLE t1 REORGANIZE PARTITION pMAX INTO +(PARTITION p3 VALUES LESS THAN (3), +PARTITION pMAX VALUES LESS THAN MAXVALUE); +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SHOW WARNINGS; +Level Code Message +Error 1205 Lock wait timeout exceeded; try restarting transaction +t1.frm +t1.par +# Connection default +SELECT * FROM t1; +a b +1 2001-01-01 +2 2002-02-02 +3 2003-03-03 +COMMIT; +DROP TABLE t1; diff --git a/mysql-test/t/partition_innodb-master.opt b/mysql-test/t/partition_innodb-master.opt new file mode 100644 index 00000000000..462f8fbe828 --- /dev/null +++ b/mysql-test/t/partition_innodb-master.opt @@ -0,0 +1 @@ +--innodb_lock_wait_timeout=1 diff --git a/mysql-test/t/partition_innodb.test b/mysql-test/t/partition_innodb.test index aba28b76f01..b7fe4477a13 100644 --- a/mysql-test/t/partition_innodb.test +++ b/mysql-test/t/partition_innodb.test @@ -5,6 +5,8 @@ drop table if exists t1; --enable_warnings +let $MYSQLD_DATADIR= `SELECT @@datadir`; + # # Bug#47029: Crash when reorganize partition with subpartition # @@ -296,6 +298,47 @@ CREATE TABLE t1 (a INT) ENGINE=InnoDB PARTITION BY list(a) (PARTITION p1 VALUES IN (1)); CREATE INDEX i1 ON t1 (a); DROP TABLE t1; -let $MYSQLD_DATADIR= `SELECT @@datadir`; + # Before the fix it should show extra file like #sql-2405_2.par --list_files $MYSQLD_DATADIR/test/ * + +--echo # +--echo # Bug#47343: InnoDB fails to clean-up after lock wait timeout on +--echo # REORGANIZE PARTITION +--echo # +CREATE TABLE t1 ( + a INT, + b DATE NOT NULL, + PRIMARY KEY (a, b) +) ENGINE=InnoDB +PARTITION BY RANGE (a) ( + PARTITION pMAX VALUES LESS THAN MAXVALUE +) ; + +INSERT INTO t1 VALUES (1, '2001-01-01'), (2, '2002-02-02'), (3, '2003-03-03'); + +START TRANSACTION; +SELECT * FROM t1 FOR UPDATE; + +connect (con1, localhost, root,,); +--echo # Connection con1 +--error ER_LOCK_WAIT_TIMEOUT +ALTER TABLE t1 REORGANIZE PARTITION pMAX INTO +(PARTITION p3 VALUES LESS THAN (3), + PARTITION pMAX VALUES LESS THAN MAXVALUE); +SHOW WARNINGS; +--error ER_LOCK_WAIT_TIMEOUT +ALTER TABLE t1 REORGANIZE PARTITION pMAX INTO +(PARTITION p3 VALUES LESS THAN (3), + PARTITION pMAX VALUES LESS THAN MAXVALUE); +SHOW WARNINGS; + +#Contents of the 'test' database directory: +--list_files $MYSQLD_DATADIR/test + +disconnect con1; +connection default; +--echo # Connection default +SELECT * FROM t1; +COMMIT; +DROP TABLE t1; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index b854e270029..555a0b97ddd 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1215,17 +1215,28 @@ int ha_partition::prepare_new_partition(TABLE *tbl, partition_element *p_elem) { int error; - bool create_flag= FALSE; DBUG_ENTER("prepare_new_partition"); if ((error= set_up_table_before_create(tbl, part_name, create_info, 0, p_elem))) - goto error; + goto error_create; if ((error= file->ha_create(part_name, tbl, create_info))) - goto error; - create_flag= TRUE; + { + /* + Added for safety, InnoDB reports HA_ERR_FOUND_DUPP_KEY + if the table/partition already exists. + If we return that error code, then print_error would try to + get_dup_key on a non-existing partition. + So return a more reasonable error code. + */ + if (error == HA_ERR_FOUND_DUPP_KEY) + error= HA_ERR_TABLE_EXIST; + goto error_create; + } + DBUG_PRINT("info", ("partition %s created", part_name)); if ((error= file->ha_open(tbl, part_name, m_mode, m_open_test_lock))) - goto error; + goto error_open; + DBUG_PRINT("info", ("partition %s opened", part_name)); /* Note: if you plan to add another call that may return failure, better to do it before external_lock() as cleanup_new_partition() @@ -1233,12 +1244,15 @@ int ha_partition::prepare_new_partition(TABLE *tbl, Otherwise see description for cleanup_new_partition(). */ if ((error= file->ha_external_lock(ha_thd(), m_lock_type))) - goto error; + goto error_external_lock; + DBUG_PRINT("info", ("partition %s external locked", part_name)); DBUG_RETURN(0); -error: - if (create_flag) - VOID(file->ha_delete_table(part_name)); +error_external_lock: + VOID(file->close()); +error_open: + VOID(file->ha_delete_table(part_name)); +error_create: DBUG_RETURN(error); } @@ -1272,19 +1286,23 @@ error: void ha_partition::cleanup_new_partition(uint part_count) { - handler **save_m_file= m_file; DBUG_ENTER("ha_partition::cleanup_new_partition"); - if (m_added_file && m_added_file[0]) + if (m_added_file) { - m_file= m_added_file; + THD *thd= ha_thd(); + handler **file= m_added_file; + while ((part_count > 0) && (*file)) + { + (*file)->ha_external_lock(thd, F_UNLCK); + (*file)->close(); + + /* Leave the (*file)->ha_delete_table(part_name) to the ddl-log */ + + file++; + part_count--; + } m_added_file= NULL; - - external_lock(ha_thd(), F_UNLCK); - /* delete_table also needed, a bit more complex */ - close(); - - m_file= save_m_file; } DBUG_VOID_RETURN; } @@ -1590,7 +1608,15 @@ int ha_partition::change_partitions(HA_CREATE_INFO *create_info, part_elem->part_state= PART_TO_BE_DROPPED; } m_new_file= new_file_array; - DBUG_RETURN(copy_partitions(copied, deleted)); + if ((error= copy_partitions(copied, deleted))) + { + /* + Close and unlock the new temporary partitions. + They will later be deleted through the ddl-log. + */ + cleanup_new_partition(part_count); + } + DBUG_RETURN(error); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index eaea6e55b09..7eabc1887f9 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6954,7 +6954,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, /* If the query was killed then this function must fail. */ - return result || thd->killed; + return result || (thd ? thd->killed : 0); } diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index e0697f563ea..441adc9ddd9 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -5708,8 +5708,7 @@ static bool write_log_drop_partition(ALTER_PARTITION_PARAM_TYPE *lpt) part_info->first_log_entry= NULL; build_table_filename(path, sizeof(path) - 1, lpt->db, lpt->table_name, "", 0); - build_table_filename(tmp_path, sizeof(tmp_path) - 1, lpt->db, - lpt->table_name, "#", 0); + build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt); pthread_mutex_lock(&LOCK_gdl); if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path, FALSE)) @@ -5765,8 +5764,7 @@ static bool write_log_add_change_partition(ALTER_PARTITION_PARAM_TYPE *lpt) build_table_filename(path, sizeof(path) - 1, lpt->db, lpt->table_name, "", 0); - build_table_filename(tmp_path, sizeof(tmp_path) - 1, lpt->db, - lpt->table_name, "#", 0); + build_table_shadow_filename(tmp_path, sizeof(tmp_path) - 1, lpt); pthread_mutex_lock(&LOCK_gdl); if (write_log_dropped_partitions(lpt, &next_entry, (const char*)path, FALSE)) @@ -5991,7 +5989,7 @@ void handle_alter_part_error(ALTER_PARTITION_PARAM_TYPE *lpt, partition_info *part_info= lpt->part_info; DBUG_ENTER("handle_alter_part_error"); - if (!part_info->first_log_entry && + if (part_info->first_log_entry && execute_ddl_log_entry(current_thd, part_info->first_log_entry->entry_pos)) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3b7354111ba..0e36ecfcb46 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -647,7 +647,7 @@ static bool read_ddl_log_file_entry(uint entry_no) Write one entry from ddl log file SYNOPSIS write_ddl_log_file_entry() - entry_no Entry number to read + entry_no Entry number to write RETURN VALUES TRUE Error FALSE Success @@ -748,10 +748,10 @@ static uint read_ddl_log_header() else successful_open= TRUE; } - entry_no= uint4korr(&file_entry_buf[DDL_LOG_NUM_ENTRY_POS]); - global_ddl_log.name_len= uint4korr(&file_entry_buf[DDL_LOG_NAME_LEN_POS]); if (successful_open) { + entry_no= uint4korr(&file_entry_buf[DDL_LOG_NUM_ENTRY_POS]); + global_ddl_log.name_len= uint4korr(&file_entry_buf[DDL_LOG_NAME_LEN_POS]); global_ddl_log.io_size= uint4korr(&file_entry_buf[DDL_LOG_IO_SIZE_POS]); DBUG_ASSERT(global_ddl_log.io_size <= sizeof(global_ddl_log.file_entry_buf)); @@ -832,6 +832,7 @@ static bool init_ddl_log() goto end; global_ddl_log.io_size= IO_SIZE; + global_ddl_log.name_len= FN_LEN; create_ddl_log_file_name(file_name); if ((global_ddl_log.file_id= my_create(file_name, CREATE_MODE, @@ -884,6 +885,13 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry) { DBUG_RETURN(FALSE); } + DBUG_PRINT("ddl_log", + ("execute type %c next %u name '%s' from_name '%s' handler '%s'", + ddl_log_entry->action_type, + ddl_log_entry->next_entry, + ddl_log_entry->name, + ddl_log_entry->from_name, + ddl_log_entry->handler_name)); handler_name.str= (char*)ddl_log_entry->handler_name; handler_name.length= strlen(ddl_log_entry->handler_name); init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0); @@ -1091,6 +1099,15 @@ bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry, DBUG_RETURN(TRUE); } error= FALSE; + DBUG_PRINT("ddl_log", + ("write type %c next %u name '%s' from_name '%s' handler '%s'", + (char) global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS], + ddl_log_entry->next_entry, + (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS], + (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + + FN_LEN], + (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + + (2*FN_LEN)])); if (write_ddl_log_file_entry((*active_entry)->entry_pos)) { error= TRUE; From 81391bd00c5b3e577fc88e142406eb288a26a0ff Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 19 Jan 2010 13:03:40 +0400 Subject: [PATCH 080/157] Bug#49501 Inefficient information_schema check (system collation) added check_length optimization for I_S_NAME comparison sql/event_data_objects.cc: added check_length optimization for I_S_NAME comparison sql/events.cc: added check_length optimization for I_S_NAME comparison sql/mysql_priv.h: added check_length optimization for I_S_NAME comparison sql/repl_failsafe.cc: added check_length optimization for I_S_NAME comparison sql/sql_db.cc: added check_length optimization for I_S_NAME comparison sql/sql_parse.cc: added check_length optimization for I_S_NAME comparison sql/sql_show.cc: added check_length optimization for I_S_NAME comparison sql/sql_view.cc: added check_length optimization for I_S_NAME comparison sql/table.cc: added check_length optimization for I_S_NAME comparison --- sql/event_data_objects.cc | 2 +- sql/events.cc | 15 +++++++++------ sql/mysql_priv.h | 8 ++++++-- sql/repl_failsafe.cc | 2 +- sql/sql_db.cc | 5 ++--- sql/sql_parse.cc | 40 ++++++++++++++++++++++----------------- sql/sql_show.cc | 9 ++++----- sql/sql_view.cc | 4 ++-- sql/table.cc | 5 +---- 9 files changed, 49 insertions(+), 41 deletions(-) diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index f2ec0e8cf64..92e237a17b7 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -1401,7 +1401,7 @@ Event_job_data::execute(THD *thd, bool drop) #endif if (check_access(thd, EVENT_ACL, dbname.str, - 0, 0, 0, is_schema_db(dbname.str))) + 0, 0, 0, is_schema_db(dbname.str, dbname.length))) { /* This aspect of behavior is defined in the worklog, diff --git a/sql/events.cc b/sql/events.cc index 458ad61718d..790e6a61699 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -415,7 +415,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, DBUG_ASSERT(parse_data->expression || parse_data->execute_at); if (check_access(thd, EVENT_ACL, parse_data->dbname.str, 0, 0, 0, - is_schema_db(parse_data->dbname.str))) + is_schema_db(parse_data->dbname.str, + parse_data->dbname.length))) DBUG_RETURN(TRUE); if (check_db_dir_existence(parse_data->dbname.str)) @@ -526,7 +527,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, DBUG_RETURN(TRUE); if (check_access(thd, EVENT_ACL, parse_data->dbname.str, 0, 0, 0, - is_schema_db(parse_data->dbname.str))) + is_schema_db(parse_data->dbname.str, + parse_data->dbname.length))) DBUG_RETURN(TRUE); if (new_dbname) /* It's a rename */ @@ -548,7 +550,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, access it. */ if (check_access(thd, EVENT_ACL, new_dbname->str, 0, 0, 0, - is_schema_db(new_dbname->str))) + is_schema_db(new_dbname->str, new_dbname->length))) DBUG_RETURN(TRUE); /* Check that the target database exists */ @@ -653,7 +655,7 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) DBUG_RETURN(TRUE); if (check_access(thd, EVENT_ACL, dbname.str, 0, 0, 0, - is_schema_db(dbname.str))) + is_schema_db(dbname.str, dbname.length))) DBUG_RETURN(TRUE); /* @@ -811,7 +813,7 @@ Events::show_create_event(THD *thd, LEX_STRING dbname, LEX_STRING name) DBUG_RETURN(TRUE); if (check_access(thd, EVENT_ACL, dbname.str, 0, 0, 0, - is_schema_db(dbname.str))) + is_schema_db(dbname.str, dbname.length))) DBUG_RETURN(TRUE); /* @@ -869,7 +871,8 @@ Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */) if (thd->lex->sql_command == SQLCOM_SHOW_EVENTS) { DBUG_ASSERT(thd->lex->select_lex.db); - if (!is_schema_db(thd->lex->select_lex.db) && // There is no events in I_S + if (!is_schema_db(thd->lex->select_lex.db, // There is no events in I_S + strlen(thd->lex->select_lex.db)) && check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0, 0)) DBUG_RETURN(1); db= thd->lex->select_lex.db; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index c04b1f5ae38..2be3b8f1f20 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1415,8 +1415,12 @@ bool get_schema_tables_result(JOIN *join, enum enum_schema_table_state executed_place); enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table); -#define is_schema_db(X) \ - !my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str, (X)) +inline bool is_schema_db(const char *name, size_t len) +{ + return (INFORMATION_SCHEMA_NAME.length == len && + !my_strcasecmp(system_charset_info, + INFORMATION_SCHEMA_NAME.str, name)); +} /* sql_prepare.cc */ diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index c6a05e93bf4..dda84ca8a37 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -905,7 +905,7 @@ bool load_master_data(THD* thd) if (!rpl_filter->db_ok(db) || !rpl_filter->db_ok_with_wild_table(db) || !strcmp(db,"mysql") || - is_schema_db(db)) + is_schema_db(db, strlen(db))) { *cur_table_res = 0; continue; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index e760fae41f6..22ecaa17a0c 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -618,7 +618,7 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, DBUG_ENTER("mysql_create_db"); /* do not create 'information_schema' db */ - if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.str)) + if (is_schema_db(db, strlen(db))) { my_error(ER_DB_CREATE_EXISTS, MYF(0), db); DBUG_RETURN(-1); @@ -1557,8 +1557,7 @@ bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch) } } - if (my_strcasecmp(system_charset_info, new_db_name->str, - INFORMATION_SCHEMA_NAME.str) == 0) + if (is_schema_db(new_db_name->str, new_db_name->length)) { /* Switch the current database to INFORMATION_SCHEMA. */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c3070c4a756..f0fb58e9c3e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1305,8 +1305,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, table_list.alias= table_list.table_name= conv_name.str; packet= arg_end + 1; - if (!my_strcasecmp(system_charset_info, table_list.db, - INFORMATION_SCHEMA_NAME.str)) + if (is_schema_db(table_list.db, table_list.db_length)) { ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias); if (schema_table) @@ -1368,7 +1367,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; } if (check_access(thd, CREATE_ACL, db.str , 0, 1, 0, - is_schema_db(db.str))) + is_schema_db(db.str, db.length))) break; general_log_print(thd, command, "%.*s", db.length, db.str); bzero(&create_info, sizeof(create_info)); @@ -1387,7 +1386,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL"); break; } - if (check_access(thd, DROP_ACL, db.str, 0, 1, 0, is_schema_db(db.str))) + if (check_access(thd, DROP_ACL, db.str, 0, 1, 0, + is_schema_db(db.str, db.length))) break; if (thd->locked_tables || thd->active_transaction()) { @@ -2852,7 +2852,7 @@ end_with_restore_list: &first_table->grant.privilege, 0, 0, test(first_table->schema_table)) || check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0, - is_schema_db(select_lex->db))|| + is_schema_db(select_lex->db, strlen(select_lex->db)))|| check_merge_table_access(thd, first_table->db, (TABLE_LIST *) create_info.merge_list.first)) @@ -3590,7 +3590,7 @@ end_with_restore_list: } #endif if (check_access(thd,CREATE_ACL,lex->name.str, 0, 1, 0, - is_schema_db(lex->name.str))) + is_schema_db(lex->name.str, lex->name.length))) break; res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias : lex->name.str), &create_info, 0); @@ -3625,7 +3625,7 @@ end_with_restore_list: } #endif if (check_access(thd,DROP_ACL,lex->name.str,0,1,0, - is_schema_db(lex->name.str))) + is_schema_db(lex->name.str, lex->name.length))) break; if (thd->locked_tables || thd->active_transaction()) { @@ -3659,9 +3659,12 @@ end_with_restore_list: my_error(ER_WRONG_DB_NAME, MYF(0), db->str); break; } - if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0, is_schema_db(db->str)) || - check_access(thd, DROP_ACL, db->str, 0, 1, 0, is_schema_db(db->str)) || - check_access(thd, CREATE_ACL, db->str, 0, 1, 0, is_schema_db(db->str))) + if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0, + is_schema_db(db->str, db->length)) || + check_access(thd, DROP_ACL, db->str, 0, 1, 0, + is_schema_db(db->str, db->length)) || + check_access(thd, CREATE_ACL, db->str, 0, 1, 0, + is_schema_db(db->str, db->length))) { res= 1; break; @@ -3704,7 +3707,8 @@ end_with_restore_list: break; } #endif - if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0, is_schema_db(db->str))) + if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0, + is_schema_db(db->str, db->length))) break; if (thd->locked_tables || thd->active_transaction()) { @@ -3860,7 +3864,8 @@ end_with_restore_list: first_table ? &first_table->grant.privilege : 0, first_table ? 0 : 1, 0, first_table ? (bool) first_table->schema_table : - select_lex->db ? is_schema_db(select_lex->db) : 0)) + select_lex->db ? + is_schema_db(select_lex->db, strlen(select_lex->db)) : 0)) goto error; if (thd->security_ctx->user) // If not replication @@ -4203,7 +4208,8 @@ end_with_restore_list: } if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, 0, 0, 0, - is_schema_db(lex->sphead->m_db.str))) + is_schema_db(lex->sphead->m_db.str, + lex->sphead->m_db.length))) goto create_sp_error; if (end_active_trans(thd)) @@ -4858,7 +4864,8 @@ create_sp_error: res= mysql_xa_recover(thd); break; case SQLCOM_ALTER_TABLESPACE: - if (check_access(thd, ALTER_ACL, thd->db, 0, 1, 0, thd->db ? is_schema_db(thd->db) : 0)) + if (check_access(thd, ALTER_ACL, thd->db, 0, 1, 0, + thd->db ? is_schema_db(thd->db, thd->db_length) : 0)) break; if (!(res= mysql_alter_tablespace(thd, lex->alter_tablespace_info))) my_ok(thd); @@ -5297,7 +5304,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table) if (check_access(thd, SELECT_ACL, dst_db_name, &thd->col_access, FALSE, FALSE, - is_schema_db(dst_db_name))) + is_schema_db(dst_db_name, strlen(dst_db_name)))) return TRUE; if (!thd->col_access && check_grant_db(thd, dst_db_name)) @@ -6262,8 +6269,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX); ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES); ptr->derived= table->sel; - if (!ptr->derived && !my_strcasecmp(system_charset_info, ptr->db, - INFORMATION_SCHEMA_NAME.str)) + if (!ptr->derived && is_schema_db(ptr->db, ptr->db_length)) { ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, ptr->table_name); if (!schema_table || diff --git a/sql/sql_show.cc b/sql/sql_show.cc index e55000c0f65..d4da29085b5 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -826,8 +826,7 @@ bool mysqld_show_create_db(THD *thd, char *dbname, DBUG_RETURN(TRUE); } #endif - if (!my_strcasecmp(system_charset_info, dbname, - INFORMATION_SCHEMA_NAME.str)) + if (is_schema_db(dbname, strlen(dbname))) { dbname= INFORMATION_SCHEMA_NAME.str; create.default_table_charset= system_charset_info; @@ -2780,8 +2779,8 @@ int make_db_list(THD *thd, List *files, */ if (lookup_field_vals->db_value.str) { - if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str, - lookup_field_vals->db_value.str)) + if (is_schema_db(lookup_field_vals->db_value.str, + lookup_field_vals->db_value.length)) { *with_i_schema= 1; if (files->push_back(i_s_name_copy)) @@ -5228,7 +5227,7 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table) */ if (thd->lex->sql_command != SQLCOM_SHOW_EVENTS && check_access(thd, EVENT_ACL, et.dbname.str, 0, 0, 1, - is_schema_db(et.dbname.str))) + is_schema_db(et.dbname.str, et.dbname.length))) DBUG_RETURN(0); /* ->field[0] is EVENT_CATALOG and is by default NULL */ diff --git a/sql/sql_view.cc b/sql/sql_view.cc index eca3922f17a..83cebf1e3da 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -268,11 +268,11 @@ bool create_view_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *view, table (i.e. user will not get some privileges by view creation) */ if ((check_access(thd, CREATE_VIEW_ACL, view->db, &view->grant.privilege, - 0, 0, is_schema_db(view->db)) || + 0, 0, is_schema_db(view->db, view->db_length)) || check_grant(thd, CREATE_VIEW_ACL, view, 0, 1, 0)) || (mode != VIEW_CREATE_NEW && (check_access(thd, DROP_ACL, view->db, &view->grant.privilege, - 0, 0, is_schema_db(view->db)) || + 0, 0, is_schema_db(view->db, view->db_length)) || check_grant(thd, DROP_ACL, view, 0, 1, 0)))) goto err; diff --git a/sql/table.cc b/sql/table.cc index 752b6ba0bd4..c06ecf99926 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -212,10 +212,7 @@ TABLE_CATEGORY get_table_category(const LEX_STRING *db, const LEX_STRING *name) DBUG_ASSERT(db != NULL); DBUG_ASSERT(name != NULL); - if ((db->length == INFORMATION_SCHEMA_NAME.length) && - (my_strcasecmp(system_charset_info, - INFORMATION_SCHEMA_NAME.str, - db->str) == 0)) + if (is_schema_db(db->str, db->length)) { return TABLE_CATEGORY_INFORMATION; } From 2fa49930cab5e070b5abaadbc2ab2b0899bc41b5 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 19 Jan 2010 14:48:41 +0200 Subject: [PATCH 081/157] revert of the fix for bug #45989: pushed by mistake. --- mysql-test/r/subselect.result | 12 ------------ mysql-test/t/subselect.test | 17 ----------------- sql/sql_select.cc | 2 -- 3 files changed, 31 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 99d1f18b010..f446d8feec3 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4602,16 +4602,4 @@ SELECT 1 FROM t1 GROUP BY 1 1 DROP TABLE t1; -# -# Bug #45989 take 2 : memory leak after explain encounters an -# error in the query -# -CREATE TABLE t1(a LONGTEXT); -INSERT INTO t1 VALUES (repeat('a',@@global.max_allowed_packet)); -INSERT INTO t1 VALUES (repeat('b',@@global.max_allowed_packet)); -EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1, -(SELECT DISTINCTROW a AS away FROM t1 GROUP BY a WITH ROLLUP) AS d1 -WHERE t1.a = d1.a; -ERROR 42S22: Unknown column 'd1.a' in 'where clause' -DROP TABLE t1; End of 5.1 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index eca86de1e82..a4314c45cba 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3585,21 +3585,4 @@ SELECT 1 FROM t1 GROUP BY (SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1); DROP TABLE t1; ---echo # ---echo # Bug #45989 take 2 : memory leak after explain encounters an ---echo # error in the query ---echo # - -CREATE TABLE t1(a LONGTEXT); -INSERT INTO t1 VALUES (repeat('a',@@global.max_allowed_packet)); -INSERT INTO t1 VALUES (repeat('b',@@global.max_allowed_packet)); - ---error ER_BAD_FIELD_ERROR -EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1, -(SELECT DISTINCTROW a AS away FROM t1 GROUP BY a WITH ROLLUP) AS d1 -WHERE t1.a = d1.a; - -DROP TABLE t1; - - --echo End of 5.1 tests. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 24876ffec14..644f0072b7b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5824,8 +5824,6 @@ JOIN::make_simple_join(JOIN *parent, TABLE *tmp_table) const_table_map= 0; tmp_table_param.field_count= tmp_table_param.sum_func_count= tmp_table_param.func_count= 0; - if (tmp_table_param.copy_field) - delete [] tmp_table_param.copy_field; tmp_table_param.copy_field= tmp_table_param.copy_field_end=0; first_record= sort_and_group=0; send_records= (ha_rows) 0; From d2f61748cd0a63d0c9df989d92cb36fc1c7583c5 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 23 Dec 2009 17:11:22 +0200 Subject: [PATCH 082/157] Bug #49512 : subquery with aggregate function crash subselect_single_select_engine::exec() When a subquery doesn't need to be evaluated because it returns only aggregate functions and these aggregates can be calculated from the metadata about the table it was not updating all the relevant members of the JOIN structure to reflect that this is a constant query. This caused problems to the enclosing subquery ('<> SOME' in the test case above) trying to read some data about the tables. Fixed by setting const_tables to the number of tables when the SELECT is optimized away. --- mysql-test/r/subselect.result | 13 +++++++++++++ mysql-test/t/subselect.test | 15 +++++++++++++++ sql/sql_select.cc | 1 + 3 files changed, 29 insertions(+) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index f446d8feec3..dc3cff68731 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4602,4 +4602,17 @@ SELECT 1 FROM t1 GROUP BY 1 1 DROP TABLE t1; +# +# Bug #49512 : subquery with aggregate function crash +# subselect_single_select_engine::exec() +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(); +# should not crash +SELECT 1 FROM t1 WHERE a <> SOME +( +SELECT MAX((SELECT a FROM t1 LIMIT 1)) AS d +FROM t1,t1 a +); +1 +DROP TABLE t1; End of 5.1 tests. diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index a4314c45cba..027578fc6bd 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3585,4 +3585,19 @@ SELECT 1 FROM t1 GROUP BY (SELECT LAST_INSERT_ID() FROM t1 ORDER BY MIN(a) ASC LIMIT 1); DROP TABLE t1; +--echo # +--echo # Bug #49512 : subquery with aggregate function crash +--echo # subselect_single_select_engine::exec() + +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(); + +--echo # should not crash +SELECT 1 FROM t1 WHERE a <> SOME +( + SELECT MAX((SELECT a FROM t1 LIMIT 1)) AS d + FROM t1,t1 a +); +DROP TABLE t1; + --echo End of 5.1 tests. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 644f0072b7b..d5ce32902c4 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -942,6 +942,7 @@ JOIN::optimize() DBUG_PRINT("info",("Select tables optimized away")); zero_result_cause= "Select tables optimized away"; tables_list= 0; // All tables resolved + const_tables= tables; /* Extract all table-independent conditions and replace the WHERE clause with them. All other conditions were computed by opt_sum_query From 416df0eaada5b644931f5b3b15f897a376641a4d Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 24 Dec 2009 15:20:58 +0000 Subject: [PATCH 083/157] BUG#48738: post-push fix. Multi-platform test improvements, mainly to make the test run gracefully on windows. There was also a syntax error in windows part of the test. --- .../r/binlog_delete_and_flush_index.result | 14 ++- .../t/binlog_delete_and_flush_index.test | 95 ++++--------------- 2 files changed, 29 insertions(+), 80 deletions(-) diff --git a/mysql-test/r/binlog_delete_and_flush_index.result b/mysql-test/r/binlog_delete_and_flush_index.result index 153900f3081..7500c17759c 100644 --- a/mysql-test/r/binlog_delete_and_flush_index.result +++ b/mysql-test/r/binlog_delete_and_flush_index.result @@ -2,7 +2,9 @@ RESET MASTER; CREATE TABLE t1 (a int); ### assertion: index file contains regular entries SET @index=LOAD_FILE('MYSQLD_DATADIR/master-bin.index'); -master-bin.000001 +SELECT @index; +@index +MYSQLD_DATADIR/master-bin.000001 ### assertion: show original binlogs show binary logs; @@ -15,8 +17,10 @@ master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a int) FLUSH LOGS; ### assertion: index file contains renamed binlog and the new one SET @index=LOAD_FILE('MYSQLD_DATADIR/master-bin.index'); -master-bin-b34582.000001 -master-bin.000002 +SELECT @index; +@index +MYSQLD_DATADIR/master-bin-b34582.000001 +MYSQLD_DATADIR/master-bin.000002 ### assertion: original binlog content still exists, despite we ### renamed and changed the index file @@ -39,6 +43,8 @@ master-bin.000002 # ### assertion: assert that not purged binlog file exists ### assertion: show index file contents and these should match show binary logs issued above SET @index=LOAD_FILE('MYSQLD_DATADIR/master-bin.index'); -master-bin.000002 +SELECT @index; +@index +MYSQLD_DATADIR/master-bin.000002 RESET MASTER; diff --git a/mysql-test/t/binlog_delete_and_flush_index.test b/mysql-test/t/binlog_delete_and_flush_index.test index 6784043386d..2899b96e317 100644 --- a/mysql-test/t/binlog_delete_and_flush_index.test +++ b/mysql-test/t/binlog_delete_and_flush_index.test @@ -45,31 +45,10 @@ RESET MASTER; CREATE TABLE t1 (a int); -- echo ### assertion: index file contains regular entries --- replace_regex /[\\\/].*master/MYSQLD_DATADIR\/master/ +-- replace_result $datadir MYSQLD_DATADIR -- eval SET @index=LOAD_FILE('$index') -if (`SELECT convert(@@version_compile_os using latin1) - IN ('Win32','Win64','Windows')`) -{ - -- disable_query_log - -- disable_result_log - -- let $a= `SELECT REPLACE (@index, '$datadir\', '')` - -- enable_result_log - -- enable_query_log - - -- echo $a - -} -if (!`SELECT convert(@@version_compile_os using latin1) - IN ('Win32','Win64','Windows')`) -{ - -- disable_query_log - -- disable_result_log - -- let $a= `SELECT REPLACE (@index, '$datadir/', '')` - -- enable_result_log - -- enable_query_log - - -- echo $a -} +-- replace_result $datadir MYSQLD_DATADIR +SELECT @index; --echo ### assertion: show original binlogs -- source include/show_binary_logs.inc @@ -79,17 +58,23 @@ if (!`SELECT convert(@@version_compile_os using latin1) # action: copy binlogs to other names and change entries in index file -- copy_file $datadir/master-bin.000001 $datadir/master-bin-b34582.000001 --- let newbinfile=$datadir/master-bin-b34582.000001 -let INDEX_FILE=$index; +-- let newbinfile= $datadir/master-bin-b34582.000001 +-- let INDEX_FILE= $index perl; -$newbinfile= $ENV{'newbinfile'}; +use File::Spec; +$newbinfile= File::Spec->rel2abs($ENV{'newbinfile'}); $file= $ENV{'INDEX_FILE'}; open(FILE, ">$file") || die "Unable to open $file."; truncate(FILE,0); -print FILE $newbinfile . "\n"; +print FILE "$newbinfile"; close ($file); EOF +# append a new line (platform independent) +-- append_file $index + +EOF + # action: should cause rotation, and creation of new binlogs FLUSH LOGS; @@ -97,31 +82,10 @@ FLUSH LOGS; -- remove_file $datadir/master-bin.000001 -- echo ### assertion: index file contains renamed binlog and the new one --- replace_regex /[\\\/].*master/MYSQLD_DATADIR\/master/ +-- replace_result $datadir MYSQLD_DATADIR -- eval SET @index=LOAD_FILE('$index') -if (`SELECT convert(@@version_compile_os using latin1) - IN ('Win32','Win64','Windows')`) -{ - -- disable_query_log - -- disable_result_log - -- let $a= `SELECT REPLACE (@index, '$datadir\', '')` - -- enable_result_log - -- enable_query_log - - -- echo $a - -} -if (!`SELECT convert(@@version_compile_os using latin1) - IN ('Win32','Win64','Windows')`) -{ - -- disable_query_log - -- disable_result_log - -- let $a= `SELECT REPLACE (@index, '$datadir/', '')` - -- enable_result_log - -- enable_query_log - - -- echo $a -} +-- replace_result $datadir MYSQLD_DATADIR +SELECT @index; -- echo ### assertion: original binlog content still exists, despite we -- echo ### renamed and changed the index file @@ -147,30 +111,9 @@ DROP TABLE t1; -- file_exists $datadir/$current_binlog -- echo ### assertion: show index file contents and these should match show binary logs issued above --- replace_regex /[\\\/].*master/MYSQLD_DATADIR\/master/ +-- replace_result $datadir MYSQLD_DATADIR -- eval SET @index=LOAD_FILE('$index') -if (`SELECT convert(@@version_compile_os using latin1) - IN ('Win32','Win64','Windows')`) -{ - -- disable_query_log - -- disable_result_log - -- let $a= `SELECT REPLACE (@index, '$datadir\', '')` - -- enable_result_log - -- enable_query_log - - -- echo $a - -} -if (!`SELECT convert(@@version_compile_os using latin1) - IN ('Win32','Win64','Windows')`) -{ - -- disable_query_log - -- disable_result_log - -- let $a= `SELECT REPLACE (@index, '$datadir/', '')` - -- enable_result_log - -- enable_query_log - - -- echo $a -} +-- replace_result $datadir MYSQLD_DATADIR +SELECT @index; RESET MASTER; From 71061de025de2e9bffaaecdd182ad7f7ccd924d0 Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Wed, 30 Dec 2009 23:06:14 +0100 Subject: [PATCH 084/157] Removed unwanted Perl DBI dependency --- support-files/mysql.spec.sh | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 8209c4560c6..b6d822d8719 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -65,6 +65,19 @@ # See BUG#998 for details. %define _unpackaged_files_terminate_build 0 +# ------------------------------------------------------------------------------ +# RPM build tools now automatically detects Perl module dependencies. This +# detection gives problems as it is broken in some versions, and it also +# give unwanted dependencies from mandatory scripts in our package. +# Might not be possible to disable in all RPM tool versions, but here we +# try. We keep the "AutoReqProv: no" for the "test" sub package, as disabling +# here might fail, and that package has the most problems. +# See http://fedoraproject.org/wiki/Packaging/Perl#Filtering_Requires:_and_Provides +# http://www.wideopen.com/archives/rpm-list/2002-October/msg00343.html +# ------------------------------------------------------------------------------ +%undefine __perl_provides +%undefine __perl_requires + %define see_base For a description of MySQL see the base MySQL RPM or http://www.mysql.com # On SuSE 9 no separate "debuginfo" package is built. To enable basic @@ -205,7 +218,7 @@ They should be used with caution. %endif %package test -Requires: %{name}-client perl-DBI perl +Requires: %{name}-client perl Summary: MySQL - Test suite Group: Applications/Databases Provides: mysql-test From 2b2ce3d6cb01a36cd35191e8670dcb023420c84e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Dec 2009 11:33:10 +0800 Subject: [PATCH 085/157] Bug #49137 Replication failure on SBR/MBR + multi-table DROP TEMPORARY TABLE In statement-based or mixed-mode replication, use DROP TEMPORARY TABLE to drop multiple tables causes different errors on master and slave, when one or more of these tables do not exist. Because when executed on slave, it would automatically add IF EXISTS to the query to ignore all ER_BAD_TABLE_ERROR errors. To fix the problem, do not add IF EXISTS when executing DROP TEMPORARY TABLE on the slave, and clear the ER_BAD_TABLE_ERROR error after execution if the query does not expect any errors. mysql-test/r/rpl_drop_temp.result: Updated for the patch of bug#49137. mysql-test/t/rpl_drop_temp.test: Added the test file to verify if DROP MULTI TEMPORARY TABLE will cause different errors on master and slave, when one or more of these tables do not exist. sql/log_event.cc: Added code to handle above cases which are removed from sql_parse.cc sql/sql_parse.cc: Remove the code to issue the 'Unknown table' error, if the temporary table does not exist when dropping it on slave. The above cases decribed in comments will be handled later in log_event.cc. --- mysql-test/r/rpl_drop_temp.result | 14 +++++++++++++ mysql-test/t/rpl_drop_temp.test | 33 +++++++++++++++++++++++++++++++ sql/log_event.cc | 12 ++++++++++- sql/sql_parse.cc | 11 ----------- 4 files changed, 58 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/rpl_drop_temp.result b/mysql-test/r/rpl_drop_temp.result index fff179d7056..48a21b1702b 100644 --- a/mysql-test/r/rpl_drop_temp.result +++ b/mysql-test/r/rpl_drop_temp.result @@ -18,3 +18,17 @@ show status like 'Slave_open_temp_tables'; Variable_name Value Slave_open_temp_tables 0 drop database mysqltest; +DROP TEMPORARY TABLE IF EXISTS tmp1; +Warnings: +Note 1051 Unknown table 'tmp1' +CREATE TEMPORARY TABLE t1 ( a int ); +DROP TEMPORARY TABLE t1, t2; +ERROR 42S02: Unknown table 't2' +DROP TEMPORARY TABLE tmp2; +ERROR 42S02: Unknown table 'tmp2' +stop slave; +**** On Master **** +CREATE TEMPORARY TABLE tmp3 (a int); +DROP TEMPORARY TABLE tmp3; +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; +START SLAVE; diff --git a/mysql-test/t/rpl_drop_temp.test b/mysql-test/t/rpl_drop_temp.test index c22bcbe63d0..c2dc8b0ea49 100644 --- a/mysql-test/t/rpl_drop_temp.test +++ b/mysql-test/t/rpl_drop_temp.test @@ -20,5 +20,38 @@ connection slave; show status like 'Slave_open_temp_tables'; connection master; drop database mysqltest; +sync_slave_with_master; + +# +# Bug#49137 +# This test verifies if DROP MULTI TEMPORARY TABLE +# will cause different errors on master and slave, +# when one or more of these tables do not exist. +# + +connection master; +DROP TEMPORARY TABLE IF EXISTS tmp1; +CREATE TEMPORARY TABLE t1 ( a int ); +--error 1051 +DROP TEMPORARY TABLE t1, t2; +--error 1051 +DROP TEMPORARY TABLE tmp2; +sync_slave_with_master; + +connection slave; +stop slave; +wait_for_slave_to_stop; + +--echo **** On Master **** +connection master; +CREATE TEMPORARY TABLE tmp3 (a int); +DROP TEMPORARY TABLE tmp3; + +connection slave; +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; +START SLAVE; + +connection master; +sync_slave_with_master; # End of 4.1 tests diff --git a/sql/log_event.cc b/sql/log_event.cc index 40e29e58ab6..35d53c4fede 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2103,7 +2103,17 @@ START SLAVE; . Query: '%s'", expected_error, thd->query); compare_errors: - /* + /* + In the slave thread, we may sometimes execute some DROP / * 40005 + TEMPORARY * / TABLE that come from parts of binlogs (likely if we + use RESET SLAVE or CHANGE MASTER TO), while the temporary table + has already been dropped. To ignore such irrelevant "table does + not exist errors", we silently clear the error if TEMPORARY was used. + */ + if (thd->lex->drop_temporary && + thd->net.last_errno == ER_BAD_TABLE_ERROR && !expected_error) + thd->clear_error(); + /* If we expected a non-zero error code, and we don't get the same error code, and none of them should be ignored. */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 48df40f2614..61c2d70a563 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4038,17 +4038,6 @@ end_with_restore_list: } else { - /* - If this is a slave thread, we may sometimes execute some - DROP / * 40005 TEMPORARY * / TABLE - that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE - MASTER TO), while the temporary table has already been dropped. - To not generate such irrelevant "table does not exist errors", - we silently add IF EXISTS if TEMPORARY was used. - */ - if (thd->slave_thread) - lex->drop_if_exists= 1; - /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */ thd->transaction.all.modified_non_trans_table= TRUE; } From af27d4e2003a84a28007a99053aefecafd7ecd97 Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Tue, 5 Jan 2010 14:25:29 +0800 Subject: [PATCH 086/157] Bug#48776 row based replication breaks with spatial / geometry types, cause crashes! This bug is the same problem as Bug 49836 for 5.1 versions. mysql-test/suite/rpl/r/rpl_geometry.result: Test case for bug 48776 mysql-test/suite/rpl/t/rpl_geometry.test: Test case for bug 48776 sql/rpl_utility.h: Add missing case MYSQL_TYPE_GEOMETRY --- mysql-test/suite/rpl/r/rpl_geometry.result | 18 +++++++++++++++ mysql-test/suite/rpl/t/rpl_geometry.test | 26 ++++++++++++++++++++++ sql/rpl_utility.h | 1 + 3 files changed, 45 insertions(+) create mode 100644 mysql-test/suite/rpl/r/rpl_geometry.result create mode 100644 mysql-test/suite/rpl/t/rpl_geometry.test diff --git a/mysql-test/suite/rpl/r/rpl_geometry.result b/mysql-test/suite/rpl/r/rpl_geometry.result new file mode 100644 index 00000000000..9b48dba4f22 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_geometry.result @@ -0,0 +1,18 @@ +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; +create table t1(a varchar(100), +b multipoint not null, +c varchar(256)); +insert into t1 set +a='hello', +b=geomfromtext('multipoint(1 1)'), +c='geometry'; +create table t2 (a int(11) not null auto_increment primary key, +b geometrycollection default null, +c decimal(10,0)); +insert into t2(c) values (null); +drop table t1, t2; diff --git a/mysql-test/suite/rpl/t/rpl_geometry.test b/mysql-test/suite/rpl/t/rpl_geometry.test new file mode 100644 index 00000000000..eac98924b98 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_geometry.test @@ -0,0 +1,26 @@ +source include/master-slave.inc; +source include/have_binlog_format_row.inc; + +# +# Bug#48776, Bug#43784 +# +create table t1(a varchar(100), + b multipoint not null, + c varchar(256)); + +insert into t1 set + a='hello', + b=geomfromtext('multipoint(1 1)'), + c='geometry'; + +create table t2 (a int(11) not null auto_increment primary key, + b geometrycollection default null, + c decimal(10,0)); + +insert into t2(c) values (null); + +sync_slave_with_master; + +connection master; +drop table t1, t2; +source include/master-slave-end.inc; diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h index 1f4ca246ff1..d011e9aade8 100644 --- a/sql/rpl_utility.h +++ b/sql/rpl_utility.h @@ -95,6 +95,7 @@ public: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_DOUBLE: case MYSQL_TYPE_FLOAT: + case MYSQL_TYPE_GEOMETRY: { /* These types store a single byte. From f8758031f37840b4b1cea4f4c3aa8736b7d68f88 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Wed, 6 Jan 2010 00:44:31 +0000 Subject: [PATCH 087/157] BUG#50018: binlog corruption when table has many columns For tables with metadata sizes ranging from 251 to 255 the size of the event data (m_data_size) was being improperly calculated in the Table_map_log_event constructor. This was due to the fact that when writing the Table_map_log_event body (in Table_map_log_event::write_data_body) a call to net_store_length is made for packing the m_field_metadata_size. It happens that net_store_length uses *one* byte for storing m_field_metadata_size when it is smaller than 251 but *three* bytes when it exceeds that value. BUG 42749 had already pinpointed and fix this fact, but the fix was incomplete, as the calculation in the Table_map_log_event constructor considers 255 instead of 251 as the threshold to increment m_data_size by three. Thence, the window for having a mismatch between the number of bytes written and the number of bytes accounted in the event length (m_data_size) was left open for m_field_metadata_size values between 251 and 255. We fix this by changing the condition in the Table_map_log_event constructor to match the one in the net_store_length, ie, increment one byte if m_field_metadata_size < 251 and three if it exceeds this value. mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result: Updated result file. mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test: Changes to the original test case: added slave and moved file into the rpl suite. New test case: replicates two tables one with 250 and another with 252 metadata sizes. This exercises the usage of 1 or 3 bytes while packing the m_field_metadata_size. sql/log_event.cc: Made the m_data_size calculation for the table map log event to match the number of bytes used while packing the m_field_metadata_size value (according to net_store_length function in pack.c). --- .../suite/binlog/r/binlog_tbl_metadata.result | 156 ------ .../suite/binlog/t/binlog_tbl_metadata.test | 199 ------- .../suite/rpl/r/rpl_row_tbl_metadata.result | 437 +++++++++++++++ .../suite/rpl/t/rpl_row_tbl_metadata.test | 520 ++++++++++++++++++ sql/log_event.cc | 6 +- 5 files changed, 960 insertions(+), 358 deletions(-) delete mode 100644 mysql-test/suite/binlog/r/binlog_tbl_metadata.result delete mode 100644 mysql-test/suite/binlog/t/binlog_tbl_metadata.test create mode 100644 mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result create mode 100644 mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test diff --git a/mysql-test/suite/binlog/r/binlog_tbl_metadata.result b/mysql-test/suite/binlog/r/binlog_tbl_metadata.result deleted file mode 100644 index a2f185edc85..00000000000 --- a/mysql-test/suite/binlog/r/binlog_tbl_metadata.result +++ /dev/null @@ -1,156 +0,0 @@ -RESET MASTER; -DROP TABLE IF EXISTS `t1`; -CREATE TABLE `t1` ( -`c1` int(11) NOT NULL AUTO_INCREMENT, -`c2` varchar(30) NOT NULL, -`c3` varchar(30) DEFAULT NULL, -`c4` varchar(30) DEFAULT NULL, -`c5` varchar(30) DEFAULT NULL, -`c6` varchar(30) DEFAULT NULL, -`c7` varchar(30) DEFAULT NULL, -`c8` varchar(30) DEFAULT NULL, -`c9` varchar(30) DEFAULT NULL, -`c10` varchar(30) DEFAULT NULL, -`c11` varchar(30) DEFAULT NULL, -`c12` varchar(30) DEFAULT NULL, -`c13` varchar(30) DEFAULT NULL, -`c14` varchar(30) DEFAULT NULL, -`c15` varchar(30) DEFAULT NULL, -`c16` varchar(30) DEFAULT NULL, -`c17` varchar(30) DEFAULT NULL, -`c18` varchar(30) DEFAULT NULL, -`c19` varchar(30) DEFAULT NULL, -`c20` varchar(30) DEFAULT NULL, -`c21` varchar(30) DEFAULT NULL, -`c22` varchar(30) DEFAULT NULL, -`c23` varchar(30) DEFAULT NULL, -`c24` varchar(30) DEFAULT NULL, -`c25` varchar(30) DEFAULT NULL, -`c26` varchar(30) DEFAULT NULL, -`c27` varchar(30) DEFAULT NULL, -`c28` varchar(30) DEFAULT NULL, -`c29` varchar(30) DEFAULT NULL, -`c30` varchar(30) DEFAULT NULL, -`c31` varchar(30) DEFAULT NULL, -`c32` varchar(30) DEFAULT NULL, -`c33` varchar(30) DEFAULT NULL, -`c34` varchar(30) DEFAULT NULL, -`c35` varchar(30) DEFAULT NULL, -`c36` varchar(30) DEFAULT NULL, -`c37` varchar(30) DEFAULT NULL, -`c38` varchar(30) DEFAULT NULL, -`c39` varchar(30) DEFAULT NULL, -`c40` varchar(30) DEFAULT NULL, -`c41` varchar(30) DEFAULT NULL, -`c42` varchar(30) DEFAULT NULL, -`c43` varchar(30) DEFAULT NULL, -`c44` varchar(30) DEFAULT NULL, -`c45` varchar(30) DEFAULT NULL, -`c46` varchar(30) DEFAULT NULL, -`c47` varchar(30) DEFAULT NULL, -`c48` varchar(30) DEFAULT NULL, -`c49` varchar(30) DEFAULT NULL, -`c50` varchar(30) DEFAULT NULL, -`c51` varchar(30) DEFAULT NULL, -`c52` varchar(30) DEFAULT NULL, -`c53` varchar(30) DEFAULT NULL, -`c54` varchar(30) DEFAULT NULL, -`c55` varchar(30) DEFAULT NULL, -`c56` varchar(30) DEFAULT NULL, -`c57` varchar(30) DEFAULT NULL, -`c58` varchar(30) DEFAULT NULL, -`c59` varchar(30) DEFAULT NULL, -`c60` varchar(30) DEFAULT NULL, -`c61` varchar(30) DEFAULT NULL, -`c62` varchar(30) DEFAULT NULL, -`c63` varchar(30) DEFAULT NULL, -`c64` varchar(30) DEFAULT NULL, -`c65` varchar(30) DEFAULT NULL, -`c66` varchar(30) DEFAULT NULL, -`c67` varchar(30) DEFAULT NULL, -`c68` varchar(30) DEFAULT NULL, -`c69` varchar(30) DEFAULT NULL, -`c70` varchar(30) DEFAULT NULL, -`c71` varchar(30) DEFAULT NULL, -`c72` varchar(30) DEFAULT NULL, -`c73` varchar(30) DEFAULT NULL, -`c74` varchar(30) DEFAULT NULL, -`c75` varchar(30) DEFAULT NULL, -`c76` varchar(30) DEFAULT NULL, -`c77` varchar(30) DEFAULT NULL, -`c78` varchar(30) DEFAULT NULL, -`c79` varchar(30) DEFAULT NULL, -`c80` varchar(30) DEFAULT NULL, -`c81` varchar(30) DEFAULT NULL, -`c82` varchar(30) DEFAULT NULL, -`c83` varchar(30) DEFAULT NULL, -`c84` varchar(30) DEFAULT NULL, -`c85` varchar(30) DEFAULT NULL, -`c86` varchar(30) DEFAULT NULL, -`c87` varchar(30) DEFAULT NULL, -`c88` varchar(30) DEFAULT NULL, -`c89` varchar(30) DEFAULT NULL, -`c90` varchar(30) DEFAULT NULL, -`c91` varchar(30) DEFAULT NULL, -`c92` varchar(30) DEFAULT NULL, -`c93` varchar(30) DEFAULT NULL, -`c94` varchar(30) DEFAULT NULL, -`c95` varchar(30) DEFAULT NULL, -`c96` varchar(30) DEFAULT NULL, -`c97` varchar(30) DEFAULT NULL, -`c98` varchar(30) DEFAULT NULL, -`c99` varchar(30) DEFAULT NULL, -`c100` varchar(30) DEFAULT NULL, -`c101` varchar(30) DEFAULT NULL, -`c102` varchar(30) DEFAULT NULL, -`c103` varchar(30) DEFAULT NULL, -`c104` varchar(30) DEFAULT NULL, -`c105` varchar(30) DEFAULT NULL, -`c106` varchar(30) DEFAULT NULL, -`c107` varchar(30) DEFAULT NULL, -`c108` varchar(30) DEFAULT NULL, -`c109` varchar(30) DEFAULT NULL, -`c110` varchar(30) DEFAULT NULL, -`c111` varchar(30) DEFAULT NULL, -`c112` varchar(30) DEFAULT NULL, -`c113` varchar(30) DEFAULT NULL, -`c114` varchar(30) DEFAULT NULL, -`c115` varchar(30) DEFAULT NULL, -`c116` varchar(30) DEFAULT NULL, -`c117` varchar(30) DEFAULT NULL, -`c118` varchar(30) DEFAULT NULL, -`c119` varchar(30) DEFAULT NULL, -`c120` varchar(30) DEFAULT NULL, -`c121` varchar(30) DEFAULT NULL, -`c122` varchar(30) DEFAULT NULL, -`c123` varchar(30) DEFAULT NULL, -`c124` varchar(30) DEFAULT NULL, -`c125` varchar(30) DEFAULT NULL, -`c126` varchar(30) DEFAULT NULL, -`c127` varchar(30) DEFAULT NULL, -`c128` varchar(30) DEFAULT NULL, -`c129` varchar(30) DEFAULT NULL, -`c130` varchar(30) DEFAULT NULL, -`c131` varchar(30) DEFAULT NULL, -`c132` varchar(30) DEFAULT NULL, -`c133` varchar(30) DEFAULT NULL, -`c134` varchar(30) DEFAULT NULL, -`c135` varchar(30) DEFAULT NULL, -`c136` varchar(30) DEFAULT NULL, -`c137` varchar(30) DEFAULT NULL, -`c138` varchar(30) DEFAULT NULL, -`c139` varchar(30) DEFAULT NULL, -`c140` varchar(30) DEFAULT NULL, -`c141` varchar(30) DEFAULT NULL, -`c142` varchar(30) DEFAULT NULL, -`c143` varchar(30) DEFAULT NULL, -`c144` varchar(30) DEFAULT NULL, -`c145` varchar(30) DEFAULT NULL, -`c146` varchar(30) DEFAULT NULL, -PRIMARY KEY (`c1`) -) ENGINE=InnoDB; -LOCK TABLES `t1` WRITE; -INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); -DROP TABLE `t1`; -FLUSH LOGS; -=== Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. diff --git a/mysql-test/suite/binlog/t/binlog_tbl_metadata.test b/mysql-test/suite/binlog/t/binlog_tbl_metadata.test deleted file mode 100644 index 5e847ab5fbd..00000000000 --- a/mysql-test/suite/binlog/t/binlog_tbl_metadata.test +++ /dev/null @@ -1,199 +0,0 @@ -# -# BUG#42749: infinite loop writing to row based binlog - processlist shows -# "freeing items" -# -# WHY -# === -# -# This bug would make table map event to report data_written one byte less -# than what would actually be written in its body. This would cause one byte shorter -# event end_log_pos. The ultimate impact was that it would make fixing the -# position in MYSQL_BIN_LOG::write_cache bogus or end up in an infinite loop. -# -# HOW -# === -# -# Checking that the patch fixes the problem is done as follows: -# i) a table with several fields is created; -# ii) an insert is performed; -# iii) the logs are flushed; -# iv) mysqlbinlog is used to check if it succeeds. -# -# In step iv), before the bug was fixed, the test case would fail with -# mysqlbinlog reporting that it was unable to succeed in reading the event. -# - --- source include/have_log_bin.inc --- source include/have_innodb.inc --- source include/have_binlog_format_row.inc --- connection default - -RESET MASTER; - --- disable_warnings -DROP TABLE IF EXISTS `t1`; --- enable_warnings - -CREATE TABLE `t1` ( - `c1` int(11) NOT NULL AUTO_INCREMENT, - `c2` varchar(30) NOT NULL, - `c3` varchar(30) DEFAULT NULL, - `c4` varchar(30) DEFAULT NULL, - `c5` varchar(30) DEFAULT NULL, - `c6` varchar(30) DEFAULT NULL, - `c7` varchar(30) DEFAULT NULL, - `c8` varchar(30) DEFAULT NULL, - `c9` varchar(30) DEFAULT NULL, - `c10` varchar(30) DEFAULT NULL, - `c11` varchar(30) DEFAULT NULL, - `c12` varchar(30) DEFAULT NULL, - `c13` varchar(30) DEFAULT NULL, - `c14` varchar(30) DEFAULT NULL, - `c15` varchar(30) DEFAULT NULL, - `c16` varchar(30) DEFAULT NULL, - `c17` varchar(30) DEFAULT NULL, - `c18` varchar(30) DEFAULT NULL, - `c19` varchar(30) DEFAULT NULL, - `c20` varchar(30) DEFAULT NULL, - `c21` varchar(30) DEFAULT NULL, - `c22` varchar(30) DEFAULT NULL, - `c23` varchar(30) DEFAULT NULL, - `c24` varchar(30) DEFAULT NULL, - `c25` varchar(30) DEFAULT NULL, - `c26` varchar(30) DEFAULT NULL, - `c27` varchar(30) DEFAULT NULL, - `c28` varchar(30) DEFAULT NULL, - `c29` varchar(30) DEFAULT NULL, - `c30` varchar(30) DEFAULT NULL, - `c31` varchar(30) DEFAULT NULL, - `c32` varchar(30) DEFAULT NULL, - `c33` varchar(30) DEFAULT NULL, - `c34` varchar(30) DEFAULT NULL, - `c35` varchar(30) DEFAULT NULL, - `c36` varchar(30) DEFAULT NULL, - `c37` varchar(30) DEFAULT NULL, - `c38` varchar(30) DEFAULT NULL, - `c39` varchar(30) DEFAULT NULL, - `c40` varchar(30) DEFAULT NULL, - `c41` varchar(30) DEFAULT NULL, - `c42` varchar(30) DEFAULT NULL, - `c43` varchar(30) DEFAULT NULL, - `c44` varchar(30) DEFAULT NULL, - `c45` varchar(30) DEFAULT NULL, - `c46` varchar(30) DEFAULT NULL, - `c47` varchar(30) DEFAULT NULL, - `c48` varchar(30) DEFAULT NULL, - `c49` varchar(30) DEFAULT NULL, - `c50` varchar(30) DEFAULT NULL, - `c51` varchar(30) DEFAULT NULL, - `c52` varchar(30) DEFAULT NULL, - `c53` varchar(30) DEFAULT NULL, - `c54` varchar(30) DEFAULT NULL, - `c55` varchar(30) DEFAULT NULL, - `c56` varchar(30) DEFAULT NULL, - `c57` varchar(30) DEFAULT NULL, - `c58` varchar(30) DEFAULT NULL, - `c59` varchar(30) DEFAULT NULL, - `c60` varchar(30) DEFAULT NULL, - `c61` varchar(30) DEFAULT NULL, - `c62` varchar(30) DEFAULT NULL, - `c63` varchar(30) DEFAULT NULL, - `c64` varchar(30) DEFAULT NULL, - `c65` varchar(30) DEFAULT NULL, - `c66` varchar(30) DEFAULT NULL, - `c67` varchar(30) DEFAULT NULL, - `c68` varchar(30) DEFAULT NULL, - `c69` varchar(30) DEFAULT NULL, - `c70` varchar(30) DEFAULT NULL, - `c71` varchar(30) DEFAULT NULL, - `c72` varchar(30) DEFAULT NULL, - `c73` varchar(30) DEFAULT NULL, - `c74` varchar(30) DEFAULT NULL, - `c75` varchar(30) DEFAULT NULL, - `c76` varchar(30) DEFAULT NULL, - `c77` varchar(30) DEFAULT NULL, - `c78` varchar(30) DEFAULT NULL, - `c79` varchar(30) DEFAULT NULL, - `c80` varchar(30) DEFAULT NULL, - `c81` varchar(30) DEFAULT NULL, - `c82` varchar(30) DEFAULT NULL, - `c83` varchar(30) DEFAULT NULL, - `c84` varchar(30) DEFAULT NULL, - `c85` varchar(30) DEFAULT NULL, - `c86` varchar(30) DEFAULT NULL, - `c87` varchar(30) DEFAULT NULL, - `c88` varchar(30) DEFAULT NULL, - `c89` varchar(30) DEFAULT NULL, - `c90` varchar(30) DEFAULT NULL, - `c91` varchar(30) DEFAULT NULL, - `c92` varchar(30) DEFAULT NULL, - `c93` varchar(30) DEFAULT NULL, - `c94` varchar(30) DEFAULT NULL, - `c95` varchar(30) DEFAULT NULL, - `c96` varchar(30) DEFAULT NULL, - `c97` varchar(30) DEFAULT NULL, - `c98` varchar(30) DEFAULT NULL, - `c99` varchar(30) DEFAULT NULL, - `c100` varchar(30) DEFAULT NULL, - `c101` varchar(30) DEFAULT NULL, - `c102` varchar(30) DEFAULT NULL, - `c103` varchar(30) DEFAULT NULL, - `c104` varchar(30) DEFAULT NULL, - `c105` varchar(30) DEFAULT NULL, - `c106` varchar(30) DEFAULT NULL, - `c107` varchar(30) DEFAULT NULL, - `c108` varchar(30) DEFAULT NULL, - `c109` varchar(30) DEFAULT NULL, - `c110` varchar(30) DEFAULT NULL, - `c111` varchar(30) DEFAULT NULL, - `c112` varchar(30) DEFAULT NULL, - `c113` varchar(30) DEFAULT NULL, - `c114` varchar(30) DEFAULT NULL, - `c115` varchar(30) DEFAULT NULL, - `c116` varchar(30) DEFAULT NULL, - `c117` varchar(30) DEFAULT NULL, - `c118` varchar(30) DEFAULT NULL, - `c119` varchar(30) DEFAULT NULL, - `c120` varchar(30) DEFAULT NULL, - `c121` varchar(30) DEFAULT NULL, - `c122` varchar(30) DEFAULT NULL, - `c123` varchar(30) DEFAULT NULL, - `c124` varchar(30) DEFAULT NULL, - `c125` varchar(30) DEFAULT NULL, - `c126` varchar(30) DEFAULT NULL, - `c127` varchar(30) DEFAULT NULL, - `c128` varchar(30) DEFAULT NULL, - `c129` varchar(30) DEFAULT NULL, - `c130` varchar(30) DEFAULT NULL, - `c131` varchar(30) DEFAULT NULL, - `c132` varchar(30) DEFAULT NULL, - `c133` varchar(30) DEFAULT NULL, - `c134` varchar(30) DEFAULT NULL, - `c135` varchar(30) DEFAULT NULL, - `c136` varchar(30) DEFAULT NULL, - `c137` varchar(30) DEFAULT NULL, - `c138` varchar(30) DEFAULT NULL, - `c139` varchar(30) DEFAULT NULL, - `c140` varchar(30) DEFAULT NULL, - `c141` varchar(30) DEFAULT NULL, - `c142` varchar(30) DEFAULT NULL, - `c143` varchar(30) DEFAULT NULL, - `c144` varchar(30) DEFAULT NULL, - `c145` varchar(30) DEFAULT NULL, - `c146` varchar(30) DEFAULT NULL, - PRIMARY KEY (`c1`) -) ENGINE=InnoDB; - -LOCK TABLES `t1` WRITE; - -INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); - -DROP TABLE `t1`; - -FLUSH LOGS; - --- echo === Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. - --- let $MYSQLD_DATADIR= `SELECT @@datadir`; --- exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog --- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog diff --git a/mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result b/mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result new file mode 100644 index 00000000000..551ece5da9d --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result @@ -0,0 +1,437 @@ +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; +RESET MASTER; +DROP TABLE IF EXISTS `t1`; +### TABLE with field_metadata_size == 290 +CREATE TABLE `t1` ( +`c1` int(11) NOT NULL AUTO_INCREMENT, +`c2` varchar(30) NOT NULL, +`c3` varchar(30) DEFAULT NULL, +`c4` varchar(30) DEFAULT NULL, +`c5` varchar(30) DEFAULT NULL, +`c6` varchar(30) DEFAULT NULL, +`c7` varchar(30) DEFAULT NULL, +`c8` varchar(30) DEFAULT NULL, +`c9` varchar(30) DEFAULT NULL, +`c10` varchar(30) DEFAULT NULL, +`c11` varchar(30) DEFAULT NULL, +`c12` varchar(30) DEFAULT NULL, +`c13` varchar(30) DEFAULT NULL, +`c14` varchar(30) DEFAULT NULL, +`c15` varchar(30) DEFAULT NULL, +`c16` varchar(30) DEFAULT NULL, +`c17` varchar(30) DEFAULT NULL, +`c18` varchar(30) DEFAULT NULL, +`c19` varchar(30) DEFAULT NULL, +`c20` varchar(30) DEFAULT NULL, +`c21` varchar(30) DEFAULT NULL, +`c22` varchar(30) DEFAULT NULL, +`c23` varchar(30) DEFAULT NULL, +`c24` varchar(30) DEFAULT NULL, +`c25` varchar(30) DEFAULT NULL, +`c26` varchar(30) DEFAULT NULL, +`c27` varchar(30) DEFAULT NULL, +`c28` varchar(30) DEFAULT NULL, +`c29` varchar(30) DEFAULT NULL, +`c30` varchar(30) DEFAULT NULL, +`c31` varchar(30) DEFAULT NULL, +`c32` varchar(30) DEFAULT NULL, +`c33` varchar(30) DEFAULT NULL, +`c34` varchar(30) DEFAULT NULL, +`c35` varchar(30) DEFAULT NULL, +`c36` varchar(30) DEFAULT NULL, +`c37` varchar(30) DEFAULT NULL, +`c38` varchar(30) DEFAULT NULL, +`c39` varchar(30) DEFAULT NULL, +`c40` varchar(30) DEFAULT NULL, +`c41` varchar(30) DEFAULT NULL, +`c42` varchar(30) DEFAULT NULL, +`c43` varchar(30) DEFAULT NULL, +`c44` varchar(30) DEFAULT NULL, +`c45` varchar(30) DEFAULT NULL, +`c46` varchar(30) DEFAULT NULL, +`c47` varchar(30) DEFAULT NULL, +`c48` varchar(30) DEFAULT NULL, +`c49` varchar(30) DEFAULT NULL, +`c50` varchar(30) DEFAULT NULL, +`c51` varchar(30) DEFAULT NULL, +`c52` varchar(30) DEFAULT NULL, +`c53` varchar(30) DEFAULT NULL, +`c54` varchar(30) DEFAULT NULL, +`c55` varchar(30) DEFAULT NULL, +`c56` varchar(30) DEFAULT NULL, +`c57` varchar(30) DEFAULT NULL, +`c58` varchar(30) DEFAULT NULL, +`c59` varchar(30) DEFAULT NULL, +`c60` varchar(30) DEFAULT NULL, +`c61` varchar(30) DEFAULT NULL, +`c62` varchar(30) DEFAULT NULL, +`c63` varchar(30) DEFAULT NULL, +`c64` varchar(30) DEFAULT NULL, +`c65` varchar(30) DEFAULT NULL, +`c66` varchar(30) DEFAULT NULL, +`c67` varchar(30) DEFAULT NULL, +`c68` varchar(30) DEFAULT NULL, +`c69` varchar(30) DEFAULT NULL, +`c70` varchar(30) DEFAULT NULL, +`c71` varchar(30) DEFAULT NULL, +`c72` varchar(30) DEFAULT NULL, +`c73` varchar(30) DEFAULT NULL, +`c74` varchar(30) DEFAULT NULL, +`c75` varchar(30) DEFAULT NULL, +`c76` varchar(30) DEFAULT NULL, +`c77` varchar(30) DEFAULT NULL, +`c78` varchar(30) DEFAULT NULL, +`c79` varchar(30) DEFAULT NULL, +`c80` varchar(30) DEFAULT NULL, +`c81` varchar(30) DEFAULT NULL, +`c82` varchar(30) DEFAULT NULL, +`c83` varchar(30) DEFAULT NULL, +`c84` varchar(30) DEFAULT NULL, +`c85` varchar(30) DEFAULT NULL, +`c86` varchar(30) DEFAULT NULL, +`c87` varchar(30) DEFAULT NULL, +`c88` varchar(30) DEFAULT NULL, +`c89` varchar(30) DEFAULT NULL, +`c90` varchar(30) DEFAULT NULL, +`c91` varchar(30) DEFAULT NULL, +`c92` varchar(30) DEFAULT NULL, +`c93` varchar(30) DEFAULT NULL, +`c94` varchar(30) DEFAULT NULL, +`c95` varchar(30) DEFAULT NULL, +`c96` varchar(30) DEFAULT NULL, +`c97` varchar(30) DEFAULT NULL, +`c98` varchar(30) DEFAULT NULL, +`c99` varchar(30) DEFAULT NULL, +`c100` varchar(30) DEFAULT NULL, +`c101` varchar(30) DEFAULT NULL, +`c102` varchar(30) DEFAULT NULL, +`c103` varchar(30) DEFAULT NULL, +`c104` varchar(30) DEFAULT NULL, +`c105` varchar(30) DEFAULT NULL, +`c106` varchar(30) DEFAULT NULL, +`c107` varchar(30) DEFAULT NULL, +`c108` varchar(30) DEFAULT NULL, +`c109` varchar(30) DEFAULT NULL, +`c110` varchar(30) DEFAULT NULL, +`c111` varchar(30) DEFAULT NULL, +`c112` varchar(30) DEFAULT NULL, +`c113` varchar(30) DEFAULT NULL, +`c114` varchar(30) DEFAULT NULL, +`c115` varchar(30) DEFAULT NULL, +`c116` varchar(30) DEFAULT NULL, +`c117` varchar(30) DEFAULT NULL, +`c118` varchar(30) DEFAULT NULL, +`c119` varchar(30) DEFAULT NULL, +`c120` varchar(30) DEFAULT NULL, +`c121` varchar(30) DEFAULT NULL, +`c122` varchar(30) DEFAULT NULL, +`c123` varchar(30) DEFAULT NULL, +`c124` varchar(30) DEFAULT NULL, +`c125` varchar(30) DEFAULT NULL, +`c126` varchar(30) DEFAULT NULL, +`c127` varchar(30) DEFAULT NULL, +`c128` varchar(30) DEFAULT NULL, +`c129` varchar(30) DEFAULT NULL, +`c130` varchar(30) DEFAULT NULL, +`c131` varchar(30) DEFAULT NULL, +`c132` varchar(30) DEFAULT NULL, +`c133` varchar(30) DEFAULT NULL, +`c134` varchar(30) DEFAULT NULL, +`c135` varchar(30) DEFAULT NULL, +`c136` varchar(30) DEFAULT NULL, +`c137` varchar(30) DEFAULT NULL, +`c138` varchar(30) DEFAULT NULL, +`c139` varchar(30) DEFAULT NULL, +`c140` varchar(30) DEFAULT NULL, +`c141` varchar(30) DEFAULT NULL, +`c142` varchar(30) DEFAULT NULL, +`c143` varchar(30) DEFAULT NULL, +`c144` varchar(30) DEFAULT NULL, +`c145` varchar(30) DEFAULT NULL, +`c146` varchar(30) DEFAULT NULL, +PRIMARY KEY (`c1`) +) ENGINE=InnoDB; +LOCK TABLES `t1` WRITE; +INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); +DROP TABLE `t1`; +FLUSH LOGS; +=== Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. +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; +### TABLE with field_metadata_size == 250 +CREATE TABLE `t1` ( +`c1` int(11) NOT NULL AUTO_INCREMENT, +`c2` varchar(30) NOT NULL, +`c3` varchar(30) DEFAULT NULL, +`c4` varchar(30) DEFAULT NULL, +`c5` varchar(30) DEFAULT NULL, +`c6` varchar(30) DEFAULT NULL, +`c7` varchar(30) DEFAULT NULL, +`c8` varchar(30) DEFAULT NULL, +`c9` varchar(30) DEFAULT NULL, +`c10` varchar(30) DEFAULT NULL, +`c11` varchar(30) DEFAULT NULL, +`c12` varchar(30) DEFAULT NULL, +`c13` varchar(30) DEFAULT NULL, +`c14` varchar(30) DEFAULT NULL, +`c15` varchar(30) DEFAULT NULL, +`c16` varchar(30) DEFAULT NULL, +`c17` varchar(30) DEFAULT NULL, +`c18` varchar(30) DEFAULT NULL, +`c19` varchar(30) DEFAULT NULL, +`c20` varchar(30) DEFAULT NULL, +`c21` varchar(30) DEFAULT NULL, +`c22` varchar(30) DEFAULT NULL, +`c23` varchar(30) DEFAULT NULL, +`c24` varchar(30) DEFAULT NULL, +`c25` varchar(30) DEFAULT NULL, +`c26` varchar(30) DEFAULT NULL, +`c27` varchar(30) DEFAULT NULL, +`c28` varchar(30) DEFAULT NULL, +`c29` varchar(30) DEFAULT NULL, +`c30` varchar(30) DEFAULT NULL, +`c31` varchar(30) DEFAULT NULL, +`c32` varchar(30) DEFAULT NULL, +`c33` varchar(30) DEFAULT NULL, +`c34` varchar(30) DEFAULT NULL, +`c35` varchar(30) DEFAULT NULL, +`c36` varchar(30) DEFAULT NULL, +`c37` varchar(30) DEFAULT NULL, +`c38` varchar(30) DEFAULT NULL, +`c39` varchar(30) DEFAULT NULL, +`c40` varchar(30) DEFAULT NULL, +`c41` varchar(30) DEFAULT NULL, +`c42` varchar(30) DEFAULT NULL, +`c43` varchar(30) DEFAULT NULL, +`c44` varchar(30) DEFAULT NULL, +`c45` varchar(30) DEFAULT NULL, +`c46` varchar(30) DEFAULT NULL, +`c47` varchar(30) DEFAULT NULL, +`c48` varchar(30) DEFAULT NULL, +`c49` varchar(30) DEFAULT NULL, +`c50` varchar(30) DEFAULT NULL, +`c51` varchar(30) DEFAULT NULL, +`c52` varchar(30) DEFAULT NULL, +`c53` varchar(30) DEFAULT NULL, +`c54` varchar(30) DEFAULT NULL, +`c55` varchar(30) DEFAULT NULL, +`c56` varchar(30) DEFAULT NULL, +`c57` varchar(30) DEFAULT NULL, +`c58` varchar(30) DEFAULT NULL, +`c59` varchar(30) DEFAULT NULL, +`c60` varchar(30) DEFAULT NULL, +`c61` varchar(30) DEFAULT NULL, +`c62` varchar(30) DEFAULT NULL, +`c63` varchar(30) DEFAULT NULL, +`c64` varchar(30) DEFAULT NULL, +`c65` varchar(30) DEFAULT NULL, +`c66` varchar(30) DEFAULT NULL, +`c67` varchar(30) DEFAULT NULL, +`c68` varchar(30) DEFAULT NULL, +`c69` varchar(30) DEFAULT NULL, +`c70` varchar(30) DEFAULT NULL, +`c71` varchar(30) DEFAULT NULL, +`c72` varchar(30) DEFAULT NULL, +`c73` varchar(30) DEFAULT NULL, +`c74` varchar(30) DEFAULT NULL, +`c75` varchar(30) DEFAULT NULL, +`c76` varchar(30) DEFAULT NULL, +`c77` varchar(30) DEFAULT NULL, +`c78` varchar(30) DEFAULT NULL, +`c79` varchar(30) DEFAULT NULL, +`c80` varchar(30) DEFAULT NULL, +`c81` varchar(30) DEFAULT NULL, +`c82` varchar(30) DEFAULT NULL, +`c83` varchar(30) DEFAULT NULL, +`c84` varchar(30) DEFAULT NULL, +`c85` varchar(30) DEFAULT NULL, +`c86` varchar(30) DEFAULT NULL, +`c87` varchar(30) DEFAULT NULL, +`c88` varchar(30) DEFAULT NULL, +`c89` varchar(30) DEFAULT NULL, +`c90` varchar(30) DEFAULT NULL, +`c91` varchar(30) DEFAULT NULL, +`c92` varchar(30) DEFAULT NULL, +`c93` varchar(30) DEFAULT NULL, +`c94` varchar(30) DEFAULT NULL, +`c95` varchar(30) DEFAULT NULL, +`c96` varchar(30) DEFAULT NULL, +`c97` varchar(30) DEFAULT NULL, +`c98` varchar(30) DEFAULT NULL, +`c99` varchar(30) DEFAULT NULL, +`c100` varchar(30) DEFAULT NULL, +`c101` varchar(30) DEFAULT NULL, +`c102` varchar(30) DEFAULT NULL, +`c103` varchar(30) DEFAULT NULL, +`c104` varchar(30) DEFAULT NULL, +`c105` varchar(30) DEFAULT NULL, +`c106` varchar(30) DEFAULT NULL, +`c107` varchar(30) DEFAULT NULL, +`c108` varchar(30) DEFAULT NULL, +`c109` varchar(30) DEFAULT NULL, +`c110` varchar(30) DEFAULT NULL, +`c111` varchar(30) DEFAULT NULL, +`c112` varchar(30) DEFAULT NULL, +`c113` varchar(30) DEFAULT NULL, +`c114` varchar(30) DEFAULT NULL, +`c115` varchar(30) DEFAULT NULL, +`c116` varchar(30) DEFAULT NULL, +`c117` varchar(30) DEFAULT NULL, +`c118` varchar(30) DEFAULT NULL, +`c119` varchar(30) DEFAULT NULL, +`c120` varchar(30) DEFAULT NULL, +`c121` varchar(30) DEFAULT NULL, +`c122` varchar(30) DEFAULT NULL, +`c123` varchar(30) DEFAULT NULL, +`c124` varchar(30) DEFAULT NULL, +`c125` varchar(30) DEFAULT NULL, +`c126` varchar(30) DEFAULT NULL, +PRIMARY KEY (`c1`) +) ENGINE=InnoDB; +### TABLE with field_metadata_size == 251 +CREATE TABLE `t2` ( +`c1` float, +`c2` varchar(30) NOT NULL, +`c3` varchar(30) DEFAULT NULL, +`c4` varchar(30) DEFAULT NULL, +`c5` varchar(30) DEFAULT NULL, +`c6` varchar(30) DEFAULT NULL, +`c7` varchar(30) DEFAULT NULL, +`c8` varchar(30) DEFAULT NULL, +`c9` varchar(30) DEFAULT NULL, +`c10` varchar(30) DEFAULT NULL, +`c11` varchar(30) DEFAULT NULL, +`c12` varchar(30) DEFAULT NULL, +`c13` varchar(30) DEFAULT NULL, +`c14` varchar(30) DEFAULT NULL, +`c15` varchar(30) DEFAULT NULL, +`c16` varchar(30) DEFAULT NULL, +`c17` varchar(30) DEFAULT NULL, +`c18` varchar(30) DEFAULT NULL, +`c19` varchar(30) DEFAULT NULL, +`c20` varchar(30) DEFAULT NULL, +`c21` varchar(30) DEFAULT NULL, +`c22` varchar(30) DEFAULT NULL, +`c23` varchar(30) DEFAULT NULL, +`c24` varchar(30) DEFAULT NULL, +`c25` varchar(30) DEFAULT NULL, +`c26` varchar(30) DEFAULT NULL, +`c27` varchar(30) DEFAULT NULL, +`c28` varchar(30) DEFAULT NULL, +`c29` varchar(30) DEFAULT NULL, +`c30` varchar(30) DEFAULT NULL, +`c31` varchar(30) DEFAULT NULL, +`c32` varchar(30) DEFAULT NULL, +`c33` varchar(30) DEFAULT NULL, +`c34` varchar(30) DEFAULT NULL, +`c35` varchar(30) DEFAULT NULL, +`c36` varchar(30) DEFAULT NULL, +`c37` varchar(30) DEFAULT NULL, +`c38` varchar(30) DEFAULT NULL, +`c39` varchar(30) DEFAULT NULL, +`c40` varchar(30) DEFAULT NULL, +`c41` varchar(30) DEFAULT NULL, +`c42` varchar(30) DEFAULT NULL, +`c43` varchar(30) DEFAULT NULL, +`c44` varchar(30) DEFAULT NULL, +`c45` varchar(30) DEFAULT NULL, +`c46` varchar(30) DEFAULT NULL, +`c47` varchar(30) DEFAULT NULL, +`c48` varchar(30) DEFAULT NULL, +`c49` varchar(30) DEFAULT NULL, +`c50` varchar(30) DEFAULT NULL, +`c51` varchar(30) DEFAULT NULL, +`c52` varchar(30) DEFAULT NULL, +`c53` varchar(30) DEFAULT NULL, +`c54` varchar(30) DEFAULT NULL, +`c55` varchar(30) DEFAULT NULL, +`c56` varchar(30) DEFAULT NULL, +`c57` varchar(30) DEFAULT NULL, +`c58` varchar(30) DEFAULT NULL, +`c59` varchar(30) DEFAULT NULL, +`c60` varchar(30) DEFAULT NULL, +`c61` varchar(30) DEFAULT NULL, +`c62` varchar(30) DEFAULT NULL, +`c63` varchar(30) DEFAULT NULL, +`c64` varchar(30) DEFAULT NULL, +`c65` varchar(30) DEFAULT NULL, +`c66` varchar(30) DEFAULT NULL, +`c67` varchar(30) DEFAULT NULL, +`c68` varchar(30) DEFAULT NULL, +`c69` varchar(30) DEFAULT NULL, +`c70` varchar(30) DEFAULT NULL, +`c71` varchar(30) DEFAULT NULL, +`c72` varchar(30) DEFAULT NULL, +`c73` varchar(30) DEFAULT NULL, +`c74` varchar(30) DEFAULT NULL, +`c75` varchar(30) DEFAULT NULL, +`c76` varchar(30) DEFAULT NULL, +`c77` varchar(30) DEFAULT NULL, +`c78` varchar(30) DEFAULT NULL, +`c79` varchar(30) DEFAULT NULL, +`c80` varchar(30) DEFAULT NULL, +`c81` varchar(30) DEFAULT NULL, +`c82` varchar(30) DEFAULT NULL, +`c83` varchar(30) DEFAULT NULL, +`c84` varchar(30) DEFAULT NULL, +`c85` varchar(30) DEFAULT NULL, +`c86` varchar(30) DEFAULT NULL, +`c87` varchar(30) DEFAULT NULL, +`c88` varchar(30) DEFAULT NULL, +`c89` varchar(30) DEFAULT NULL, +`c90` varchar(30) DEFAULT NULL, +`c91` varchar(30) DEFAULT NULL, +`c92` varchar(30) DEFAULT NULL, +`c93` varchar(30) DEFAULT NULL, +`c94` varchar(30) DEFAULT NULL, +`c95` varchar(30) DEFAULT NULL, +`c96` varchar(30) DEFAULT NULL, +`c97` varchar(30) DEFAULT NULL, +`c98` varchar(30) DEFAULT NULL, +`c99` varchar(30) DEFAULT NULL, +`c100` varchar(30) DEFAULT NULL, +`c101` varchar(30) DEFAULT NULL, +`c102` varchar(30) DEFAULT NULL, +`c103` varchar(30) DEFAULT NULL, +`c104` varchar(30) DEFAULT NULL, +`c105` varchar(30) DEFAULT NULL, +`c106` varchar(30) DEFAULT NULL, +`c107` varchar(30) DEFAULT NULL, +`c108` varchar(30) DEFAULT NULL, +`c109` varchar(30) DEFAULT NULL, +`c110` varchar(30) DEFAULT NULL, +`c111` varchar(30) DEFAULT NULL, +`c112` varchar(30) DEFAULT NULL, +`c113` varchar(30) DEFAULT NULL, +`c114` varchar(30) DEFAULT NULL, +`c115` varchar(30) DEFAULT NULL, +`c116` varchar(30) DEFAULT NULL, +`c117` varchar(30) DEFAULT NULL, +`c118` varchar(30) DEFAULT NULL, +`c119` varchar(30) DEFAULT NULL, +`c120` varchar(30) DEFAULT NULL, +`c121` varchar(30) DEFAULT NULL, +`c122` varchar(30) DEFAULT NULL, +`c123` varchar(30) DEFAULT NULL, +`c124` varchar(30) DEFAULT NULL, +`c125` varchar(30) DEFAULT NULL, +`c126` varchar(30) DEFAULT NULL, +PRIMARY KEY (`c1`) +) ENGINE=InnoDB; +LOCK TABLES `t1` WRITE; +INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); +LOCK TABLES `t2` WRITE; +INSERT INTO `t2` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); +DROP TABLE `t1`; +DROP TABLE `t2`; +FLUSH LOGS; +=== Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. diff --git a/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test new file mode 100644 index 00000000000..4d7ba1e0a81 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test @@ -0,0 +1,520 @@ +# +# BUG#42749: infinite loop writing to row based binlog - processlist shows +# "freeing items" +# +# BUG#50018: binlog corruption when table has many columns +# +# WHY +# === +# +# This bug would make table map event to report data_written one +# byte less than what would actually be written in its body. This +# would cause one byte shorter event end_log_pos. The ultimate +# impact was that it would make fixing the position in +# MYSQL_BIN_LOG::write_cache bogus or end up in an infinite loop. +# +# HOW +# === +# +# Checking that the patch fixes the problem is done as follows: +# +# i) tables with several fields is created (above and below a 251 +# metadata size threshold) +# ii) an insert is performed; +# iii) the logs are flushed; +# iv) mysqlbinlog is used to check if it succeeds. +# +# In step iv), before the bug was fixed, the test case would fail +# with mysqlbinlog reporting that it was unable to succeed in +# reading the event. + +-- source include/master-slave.inc +-- source include/have_log_bin.inc +-- source include/have_innodb.inc +-- source include/have_binlog_format_row.inc +-- connection default + +RESET MASTER; + +-- disable_warnings +DROP TABLE IF EXISTS `t1`; +-- enable_warnings + +-- echo ### TABLE with field_metadata_size == 290 +CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` varchar(30) NOT NULL, + `c3` varchar(30) DEFAULT NULL, + `c4` varchar(30) DEFAULT NULL, + `c5` varchar(30) DEFAULT NULL, + `c6` varchar(30) DEFAULT NULL, + `c7` varchar(30) DEFAULT NULL, + `c8` varchar(30) DEFAULT NULL, + `c9` varchar(30) DEFAULT NULL, + `c10` varchar(30) DEFAULT NULL, + `c11` varchar(30) DEFAULT NULL, + `c12` varchar(30) DEFAULT NULL, + `c13` varchar(30) DEFAULT NULL, + `c14` varchar(30) DEFAULT NULL, + `c15` varchar(30) DEFAULT NULL, + `c16` varchar(30) DEFAULT NULL, + `c17` varchar(30) DEFAULT NULL, + `c18` varchar(30) DEFAULT NULL, + `c19` varchar(30) DEFAULT NULL, + `c20` varchar(30) DEFAULT NULL, + `c21` varchar(30) DEFAULT NULL, + `c22` varchar(30) DEFAULT NULL, + `c23` varchar(30) DEFAULT NULL, + `c24` varchar(30) DEFAULT NULL, + `c25` varchar(30) DEFAULT NULL, + `c26` varchar(30) DEFAULT NULL, + `c27` varchar(30) DEFAULT NULL, + `c28` varchar(30) DEFAULT NULL, + `c29` varchar(30) DEFAULT NULL, + `c30` varchar(30) DEFAULT NULL, + `c31` varchar(30) DEFAULT NULL, + `c32` varchar(30) DEFAULT NULL, + `c33` varchar(30) DEFAULT NULL, + `c34` varchar(30) DEFAULT NULL, + `c35` varchar(30) DEFAULT NULL, + `c36` varchar(30) DEFAULT NULL, + `c37` varchar(30) DEFAULT NULL, + `c38` varchar(30) DEFAULT NULL, + `c39` varchar(30) DEFAULT NULL, + `c40` varchar(30) DEFAULT NULL, + `c41` varchar(30) DEFAULT NULL, + `c42` varchar(30) DEFAULT NULL, + `c43` varchar(30) DEFAULT NULL, + `c44` varchar(30) DEFAULT NULL, + `c45` varchar(30) DEFAULT NULL, + `c46` varchar(30) DEFAULT NULL, + `c47` varchar(30) DEFAULT NULL, + `c48` varchar(30) DEFAULT NULL, + `c49` varchar(30) DEFAULT NULL, + `c50` varchar(30) DEFAULT NULL, + `c51` varchar(30) DEFAULT NULL, + `c52` varchar(30) DEFAULT NULL, + `c53` varchar(30) DEFAULT NULL, + `c54` varchar(30) DEFAULT NULL, + `c55` varchar(30) DEFAULT NULL, + `c56` varchar(30) DEFAULT NULL, + `c57` varchar(30) DEFAULT NULL, + `c58` varchar(30) DEFAULT NULL, + `c59` varchar(30) DEFAULT NULL, + `c60` varchar(30) DEFAULT NULL, + `c61` varchar(30) DEFAULT NULL, + `c62` varchar(30) DEFAULT NULL, + `c63` varchar(30) DEFAULT NULL, + `c64` varchar(30) DEFAULT NULL, + `c65` varchar(30) DEFAULT NULL, + `c66` varchar(30) DEFAULT NULL, + `c67` varchar(30) DEFAULT NULL, + `c68` varchar(30) DEFAULT NULL, + `c69` varchar(30) DEFAULT NULL, + `c70` varchar(30) DEFAULT NULL, + `c71` varchar(30) DEFAULT NULL, + `c72` varchar(30) DEFAULT NULL, + `c73` varchar(30) DEFAULT NULL, + `c74` varchar(30) DEFAULT NULL, + `c75` varchar(30) DEFAULT NULL, + `c76` varchar(30) DEFAULT NULL, + `c77` varchar(30) DEFAULT NULL, + `c78` varchar(30) DEFAULT NULL, + `c79` varchar(30) DEFAULT NULL, + `c80` varchar(30) DEFAULT NULL, + `c81` varchar(30) DEFAULT NULL, + `c82` varchar(30) DEFAULT NULL, + `c83` varchar(30) DEFAULT NULL, + `c84` varchar(30) DEFAULT NULL, + `c85` varchar(30) DEFAULT NULL, + `c86` varchar(30) DEFAULT NULL, + `c87` varchar(30) DEFAULT NULL, + `c88` varchar(30) DEFAULT NULL, + `c89` varchar(30) DEFAULT NULL, + `c90` varchar(30) DEFAULT NULL, + `c91` varchar(30) DEFAULT NULL, + `c92` varchar(30) DEFAULT NULL, + `c93` varchar(30) DEFAULT NULL, + `c94` varchar(30) DEFAULT NULL, + `c95` varchar(30) DEFAULT NULL, + `c96` varchar(30) DEFAULT NULL, + `c97` varchar(30) DEFAULT NULL, + `c98` varchar(30) DEFAULT NULL, + `c99` varchar(30) DEFAULT NULL, + `c100` varchar(30) DEFAULT NULL, + `c101` varchar(30) DEFAULT NULL, + `c102` varchar(30) DEFAULT NULL, + `c103` varchar(30) DEFAULT NULL, + `c104` varchar(30) DEFAULT NULL, + `c105` varchar(30) DEFAULT NULL, + `c106` varchar(30) DEFAULT NULL, + `c107` varchar(30) DEFAULT NULL, + `c108` varchar(30) DEFAULT NULL, + `c109` varchar(30) DEFAULT NULL, + `c110` varchar(30) DEFAULT NULL, + `c111` varchar(30) DEFAULT NULL, + `c112` varchar(30) DEFAULT NULL, + `c113` varchar(30) DEFAULT NULL, + `c114` varchar(30) DEFAULT NULL, + `c115` varchar(30) DEFAULT NULL, + `c116` varchar(30) DEFAULT NULL, + `c117` varchar(30) DEFAULT NULL, + `c118` varchar(30) DEFAULT NULL, + `c119` varchar(30) DEFAULT NULL, + `c120` varchar(30) DEFAULT NULL, + `c121` varchar(30) DEFAULT NULL, + `c122` varchar(30) DEFAULT NULL, + `c123` varchar(30) DEFAULT NULL, + `c124` varchar(30) DEFAULT NULL, + `c125` varchar(30) DEFAULT NULL, + `c126` varchar(30) DEFAULT NULL, + `c127` varchar(30) DEFAULT NULL, + `c128` varchar(30) DEFAULT NULL, + `c129` varchar(30) DEFAULT NULL, + `c130` varchar(30) DEFAULT NULL, + `c131` varchar(30) DEFAULT NULL, + `c132` varchar(30) DEFAULT NULL, + `c133` varchar(30) DEFAULT NULL, + `c134` varchar(30) DEFAULT NULL, + `c135` varchar(30) DEFAULT NULL, + `c136` varchar(30) DEFAULT NULL, + `c137` varchar(30) DEFAULT NULL, + `c138` varchar(30) DEFAULT NULL, + `c139` varchar(30) DEFAULT NULL, + `c140` varchar(30) DEFAULT NULL, + `c141` varchar(30) DEFAULT NULL, + `c142` varchar(30) DEFAULT NULL, + `c143` varchar(30) DEFAULT NULL, + `c144` varchar(30) DEFAULT NULL, + `c145` varchar(30) DEFAULT NULL, + `c146` varchar(30) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB; + +LOCK TABLES `t1` WRITE; + +INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); + +DROP TABLE `t1`; + +FLUSH LOGS; + +-- sync_slave_with_master +-- connection master + +-- echo === Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. + +-- let $MYSQLD_DATADIR= `SELECT @@datadir`; +-- exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog +-- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog + +-- source include/master-slave-reset.inc +-- connection master + +# Create two tables one with field_metadata_size == 250 +# and another one with field_metadata_size == 252 +# +# Each varchar field takes up to 2 metadata bytes, see: +# +# Field_varstring::do_save_field_metadata (field.cc) +# +# The integer field takes 0 bytes, see: +# +# Field::do_save_field_metadata (field.h) +# +# The float field takes 1 byte, see: +# +# Field_float::do_save_field_metadata (field.cc) +# +# We choose 250 and 252 which are the ones below and above +# the threshold for switching to use 1 or 3 bytes for the +# m_data_size increment. +# + +-- echo ### TABLE with field_metadata_size == 250 + +CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` varchar(30) NOT NULL, + `c3` varchar(30) DEFAULT NULL, + `c4` varchar(30) DEFAULT NULL, + `c5` varchar(30) DEFAULT NULL, + `c6` varchar(30) DEFAULT NULL, + `c7` varchar(30) DEFAULT NULL, + `c8` varchar(30) DEFAULT NULL, + `c9` varchar(30) DEFAULT NULL, + `c10` varchar(30) DEFAULT NULL, + `c11` varchar(30) DEFAULT NULL, + `c12` varchar(30) DEFAULT NULL, + `c13` varchar(30) DEFAULT NULL, + `c14` varchar(30) DEFAULT NULL, + `c15` varchar(30) DEFAULT NULL, + `c16` varchar(30) DEFAULT NULL, + `c17` varchar(30) DEFAULT NULL, + `c18` varchar(30) DEFAULT NULL, + `c19` varchar(30) DEFAULT NULL, + `c20` varchar(30) DEFAULT NULL, + `c21` varchar(30) DEFAULT NULL, + `c22` varchar(30) DEFAULT NULL, + `c23` varchar(30) DEFAULT NULL, + `c24` varchar(30) DEFAULT NULL, + `c25` varchar(30) DEFAULT NULL, + `c26` varchar(30) DEFAULT NULL, + `c27` varchar(30) DEFAULT NULL, + `c28` varchar(30) DEFAULT NULL, + `c29` varchar(30) DEFAULT NULL, + `c30` varchar(30) DEFAULT NULL, + `c31` varchar(30) DEFAULT NULL, + `c32` varchar(30) DEFAULT NULL, + `c33` varchar(30) DEFAULT NULL, + `c34` varchar(30) DEFAULT NULL, + `c35` varchar(30) DEFAULT NULL, + `c36` varchar(30) DEFAULT NULL, + `c37` varchar(30) DEFAULT NULL, + `c38` varchar(30) DEFAULT NULL, + `c39` varchar(30) DEFAULT NULL, + `c40` varchar(30) DEFAULT NULL, + `c41` varchar(30) DEFAULT NULL, + `c42` varchar(30) DEFAULT NULL, + `c43` varchar(30) DEFAULT NULL, + `c44` varchar(30) DEFAULT NULL, + `c45` varchar(30) DEFAULT NULL, + `c46` varchar(30) DEFAULT NULL, + `c47` varchar(30) DEFAULT NULL, + `c48` varchar(30) DEFAULT NULL, + `c49` varchar(30) DEFAULT NULL, + `c50` varchar(30) DEFAULT NULL, + `c51` varchar(30) DEFAULT NULL, + `c52` varchar(30) DEFAULT NULL, + `c53` varchar(30) DEFAULT NULL, + `c54` varchar(30) DEFAULT NULL, + `c55` varchar(30) DEFAULT NULL, + `c56` varchar(30) DEFAULT NULL, + `c57` varchar(30) DEFAULT NULL, + `c58` varchar(30) DEFAULT NULL, + `c59` varchar(30) DEFAULT NULL, + `c60` varchar(30) DEFAULT NULL, + `c61` varchar(30) DEFAULT NULL, + `c62` varchar(30) DEFAULT NULL, + `c63` varchar(30) DEFAULT NULL, + `c64` varchar(30) DEFAULT NULL, + `c65` varchar(30) DEFAULT NULL, + `c66` varchar(30) DEFAULT NULL, + `c67` varchar(30) DEFAULT NULL, + `c68` varchar(30) DEFAULT NULL, + `c69` varchar(30) DEFAULT NULL, + `c70` varchar(30) DEFAULT NULL, + `c71` varchar(30) DEFAULT NULL, + `c72` varchar(30) DEFAULT NULL, + `c73` varchar(30) DEFAULT NULL, + `c74` varchar(30) DEFAULT NULL, + `c75` varchar(30) DEFAULT NULL, + `c76` varchar(30) DEFAULT NULL, + `c77` varchar(30) DEFAULT NULL, + `c78` varchar(30) DEFAULT NULL, + `c79` varchar(30) DEFAULT NULL, + `c80` varchar(30) DEFAULT NULL, + `c81` varchar(30) DEFAULT NULL, + `c82` varchar(30) DEFAULT NULL, + `c83` varchar(30) DEFAULT NULL, + `c84` varchar(30) DEFAULT NULL, + `c85` varchar(30) DEFAULT NULL, + `c86` varchar(30) DEFAULT NULL, + `c87` varchar(30) DEFAULT NULL, + `c88` varchar(30) DEFAULT NULL, + `c89` varchar(30) DEFAULT NULL, + `c90` varchar(30) DEFAULT NULL, + `c91` varchar(30) DEFAULT NULL, + `c92` varchar(30) DEFAULT NULL, + `c93` varchar(30) DEFAULT NULL, + `c94` varchar(30) DEFAULT NULL, + `c95` varchar(30) DEFAULT NULL, + `c96` varchar(30) DEFAULT NULL, + `c97` varchar(30) DEFAULT NULL, + `c98` varchar(30) DEFAULT NULL, + `c99` varchar(30) DEFAULT NULL, + `c100` varchar(30) DEFAULT NULL, + `c101` varchar(30) DEFAULT NULL, + `c102` varchar(30) DEFAULT NULL, + `c103` varchar(30) DEFAULT NULL, + `c104` varchar(30) DEFAULT NULL, + `c105` varchar(30) DEFAULT NULL, + `c106` varchar(30) DEFAULT NULL, + `c107` varchar(30) DEFAULT NULL, + `c108` varchar(30) DEFAULT NULL, + `c109` varchar(30) DEFAULT NULL, + `c110` varchar(30) DEFAULT NULL, + `c111` varchar(30) DEFAULT NULL, + `c112` varchar(30) DEFAULT NULL, + `c113` varchar(30) DEFAULT NULL, + `c114` varchar(30) DEFAULT NULL, + `c115` varchar(30) DEFAULT NULL, + `c116` varchar(30) DEFAULT NULL, + `c117` varchar(30) DEFAULT NULL, + `c118` varchar(30) DEFAULT NULL, + `c119` varchar(30) DEFAULT NULL, + `c120` varchar(30) DEFAULT NULL, + `c121` varchar(30) DEFAULT NULL, + `c122` varchar(30) DEFAULT NULL, + `c123` varchar(30) DEFAULT NULL, + `c124` varchar(30) DEFAULT NULL, + `c125` varchar(30) DEFAULT NULL, + `c126` varchar(30) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB; + +-- echo ### TABLE with field_metadata_size == 251 + +CREATE TABLE `t2` ( + `c1` float, + `c2` varchar(30) NOT NULL, + `c3` varchar(30) DEFAULT NULL, + `c4` varchar(30) DEFAULT NULL, + `c5` varchar(30) DEFAULT NULL, + `c6` varchar(30) DEFAULT NULL, + `c7` varchar(30) DEFAULT NULL, + `c8` varchar(30) DEFAULT NULL, + `c9` varchar(30) DEFAULT NULL, + `c10` varchar(30) DEFAULT NULL, + `c11` varchar(30) DEFAULT NULL, + `c12` varchar(30) DEFAULT NULL, + `c13` varchar(30) DEFAULT NULL, + `c14` varchar(30) DEFAULT NULL, + `c15` varchar(30) DEFAULT NULL, + `c16` varchar(30) DEFAULT NULL, + `c17` varchar(30) DEFAULT NULL, + `c18` varchar(30) DEFAULT NULL, + `c19` varchar(30) DEFAULT NULL, + `c20` varchar(30) DEFAULT NULL, + `c21` varchar(30) DEFAULT NULL, + `c22` varchar(30) DEFAULT NULL, + `c23` varchar(30) DEFAULT NULL, + `c24` varchar(30) DEFAULT NULL, + `c25` varchar(30) DEFAULT NULL, + `c26` varchar(30) DEFAULT NULL, + `c27` varchar(30) DEFAULT NULL, + `c28` varchar(30) DEFAULT NULL, + `c29` varchar(30) DEFAULT NULL, + `c30` varchar(30) DEFAULT NULL, + `c31` varchar(30) DEFAULT NULL, + `c32` varchar(30) DEFAULT NULL, + `c33` varchar(30) DEFAULT NULL, + `c34` varchar(30) DEFAULT NULL, + `c35` varchar(30) DEFAULT NULL, + `c36` varchar(30) DEFAULT NULL, + `c37` varchar(30) DEFAULT NULL, + `c38` varchar(30) DEFAULT NULL, + `c39` varchar(30) DEFAULT NULL, + `c40` varchar(30) DEFAULT NULL, + `c41` varchar(30) DEFAULT NULL, + `c42` varchar(30) DEFAULT NULL, + `c43` varchar(30) DEFAULT NULL, + `c44` varchar(30) DEFAULT NULL, + `c45` varchar(30) DEFAULT NULL, + `c46` varchar(30) DEFAULT NULL, + `c47` varchar(30) DEFAULT NULL, + `c48` varchar(30) DEFAULT NULL, + `c49` varchar(30) DEFAULT NULL, + `c50` varchar(30) DEFAULT NULL, + `c51` varchar(30) DEFAULT NULL, + `c52` varchar(30) DEFAULT NULL, + `c53` varchar(30) DEFAULT NULL, + `c54` varchar(30) DEFAULT NULL, + `c55` varchar(30) DEFAULT NULL, + `c56` varchar(30) DEFAULT NULL, + `c57` varchar(30) DEFAULT NULL, + `c58` varchar(30) DEFAULT NULL, + `c59` varchar(30) DEFAULT NULL, + `c60` varchar(30) DEFAULT NULL, + `c61` varchar(30) DEFAULT NULL, + `c62` varchar(30) DEFAULT NULL, + `c63` varchar(30) DEFAULT NULL, + `c64` varchar(30) DEFAULT NULL, + `c65` varchar(30) DEFAULT NULL, + `c66` varchar(30) DEFAULT NULL, + `c67` varchar(30) DEFAULT NULL, + `c68` varchar(30) DEFAULT NULL, + `c69` varchar(30) DEFAULT NULL, + `c70` varchar(30) DEFAULT NULL, + `c71` varchar(30) DEFAULT NULL, + `c72` varchar(30) DEFAULT NULL, + `c73` varchar(30) DEFAULT NULL, + `c74` varchar(30) DEFAULT NULL, + `c75` varchar(30) DEFAULT NULL, + `c76` varchar(30) DEFAULT NULL, + `c77` varchar(30) DEFAULT NULL, + `c78` varchar(30) DEFAULT NULL, + `c79` varchar(30) DEFAULT NULL, + `c80` varchar(30) DEFAULT NULL, + `c81` varchar(30) DEFAULT NULL, + `c82` varchar(30) DEFAULT NULL, + `c83` varchar(30) DEFAULT NULL, + `c84` varchar(30) DEFAULT NULL, + `c85` varchar(30) DEFAULT NULL, + `c86` varchar(30) DEFAULT NULL, + `c87` varchar(30) DEFAULT NULL, + `c88` varchar(30) DEFAULT NULL, + `c89` varchar(30) DEFAULT NULL, + `c90` varchar(30) DEFAULT NULL, + `c91` varchar(30) DEFAULT NULL, + `c92` varchar(30) DEFAULT NULL, + `c93` varchar(30) DEFAULT NULL, + `c94` varchar(30) DEFAULT NULL, + `c95` varchar(30) DEFAULT NULL, + `c96` varchar(30) DEFAULT NULL, + `c97` varchar(30) DEFAULT NULL, + `c98` varchar(30) DEFAULT NULL, + `c99` varchar(30) DEFAULT NULL, + `c100` varchar(30) DEFAULT NULL, + `c101` varchar(30) DEFAULT NULL, + `c102` varchar(30) DEFAULT NULL, + `c103` varchar(30) DEFAULT NULL, + `c104` varchar(30) DEFAULT NULL, + `c105` varchar(30) DEFAULT NULL, + `c106` varchar(30) DEFAULT NULL, + `c107` varchar(30) DEFAULT NULL, + `c108` varchar(30) DEFAULT NULL, + `c109` varchar(30) DEFAULT NULL, + `c110` varchar(30) DEFAULT NULL, + `c111` varchar(30) DEFAULT NULL, + `c112` varchar(30) DEFAULT NULL, + `c113` varchar(30) DEFAULT NULL, + `c114` varchar(30) DEFAULT NULL, + `c115` varchar(30) DEFAULT NULL, + `c116` varchar(30) DEFAULT NULL, + `c117` varchar(30) DEFAULT NULL, + `c118` varchar(30) DEFAULT NULL, + `c119` varchar(30) DEFAULT NULL, + `c120` varchar(30) DEFAULT NULL, + `c121` varchar(30) DEFAULT NULL, + `c122` varchar(30) DEFAULT NULL, + `c123` varchar(30) DEFAULT NULL, + `c124` varchar(30) DEFAULT NULL, + `c125` varchar(30) DEFAULT NULL, + `c126` varchar(30) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB; + +LOCK TABLES `t1` WRITE; +INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); + + +LOCK TABLES `t2` WRITE; +INSERT INTO `t2` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); + +DROP TABLE `t1`; +DROP TABLE `t2`; + +FLUSH LOGS; + +-- sync_slave_with_master + +-- connection master + +-- echo === Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. + +-- let $MYSQLD_DATADIR= `SELECT @@datadir`; +-- exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog +-- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog + +-- source include/master-slave-end.inc diff --git a/sql/log_event.cc b/sql/log_event.cc index c028db3476d..d5a436cb79e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -7925,10 +7925,10 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, plus one or three bytes (see pack.c:net_store_length) for number of elements in the field metadata array. */ - if (m_field_metadata_size > 255) - m_data_size+= m_field_metadata_size + 3; - else + if (m_field_metadata_size < 251) m_data_size+= m_field_metadata_size + 1; + else + m_data_size+= m_field_metadata_size + 3; bzero(m_null_bits, num_null_bytes); for (unsigned int i= 0 ; i < m_table->s->fields ; ++i) From 0a64fbc517eef4550e5b0b75246125391f5deca1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Jan 2010 10:36:29 +0800 Subject: [PATCH 088/157] Bug #49137 Replication failure on SBR/MBR + multi-table DROP TEMPORARY TABLE Fixed valgrind failure on PB2. sql/log_event.cc: Added code to fix valgrind failure on PB2. --- sql/log_event.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 35d53c4fede..ad5c4bfeef8 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2110,8 +2110,8 @@ compare_errors: has already been dropped. To ignore such irrelevant "table does not exist errors", we silently clear the error if TEMPORARY was used. */ - if (thd->lex->drop_temporary && - thd->net.last_errno == ER_BAD_TABLE_ERROR && !expected_error) + if (thd->net.last_errno == ER_BAD_TABLE_ERROR && + !expected_error && thd->lex->drop_temporary) thd->clear_error(); /* If we expected a non-zero error code, and we don't get the same error From 98b989d7b1f250f4e245b1ca479bacd9b18ae98e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Jan 2010 13:12:40 +0800 Subject: [PATCH 089/157] Bug #49137 Replication failure on SBR/MBR + multi-table DROP TEMPORARY TABLE Fixed valgrind failure on PB2. sql/log_event.cc: Added code to fix valgrind failure on PB2. --- sql/log_event.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index ad5c4bfeef8..76fc2632cd1 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2110,8 +2110,8 @@ compare_errors: has already been dropped. To ignore such irrelevant "table does not exist errors", we silently clear the error if TEMPORARY was used. */ - if (thd->net.last_errno == ER_BAD_TABLE_ERROR && - !expected_error && thd->lex->drop_temporary) + if (thd->lex->sql_command == SQLCOM_DROP_TABLE && thd->lex->drop_temporary && + thd->net.last_errno == ER_BAD_TABLE_ERROR && !expected_error) thd->clear_error(); /* If we expected a non-zero error code, and we don't get the same error From 9eca4014e34add68eafb7b8d820d7f7920e0b8e1 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 6 Jan 2010 12:24:51 +0200 Subject: [PATCH 090/157] Addendum to Bug #49734 : fixed an unstable test case. --- mysql-test/r/union.result | 3 --- mysql-test/t/union.test | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index dce32d2ced4..43d7cade227 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -1640,9 +1640,6 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` union select `test`.`t1 # Should not crash SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY (SELECT a FROM t2 WHERE b = 12); -a -1 -2 # Should not crash SELECT * FROM t2 UNION SELECT * FROM t2 ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)); diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 91fc9546bbe..c8d5ea0f8e5 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -1144,8 +1144,10 @@ SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY (SELECT a FROM t2 WHERE b = 12); --echo # Should not crash +--disable_result_log SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY (SELECT a FROM t2 WHERE b = 12); +--enable_result_log --echo # Should not crash SELECT * FROM t2 UNION SELECT * FROM t2 From 585303295fba0ecb01da868adc59de7a04a0d484 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 7 Jan 2010 17:45:54 +0000 Subject: [PATCH 091/157] BUG#50018: binlog corruption when table has many columns Some improvements on the test case as suggested during review. --- .../suite/rpl/r/rpl_row_tbl_metadata.result | 309 ++------------ .../suite/rpl/t/rpl_row_tbl_metadata.test | 402 +++++------------- 2 files changed, 150 insertions(+), 561 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result b/mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result index 551ece5da9d..711d0d063aa 100644 --- a/mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result +++ b/mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result @@ -4,7 +4,6 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; -RESET MASTER; DROP TABLE IF EXISTS `t1`; ### TABLE with field_metadata_size == 290 CREATE TABLE `t1` ( @@ -157,9 +156,11 @@ CREATE TABLE `t1` ( PRIMARY KEY (`c1`) ) ENGINE=InnoDB; LOCK TABLES `t1` WRITE; -INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); -DROP TABLE `t1`; +INSERT INTO `t1`(c2) VALUES ('1'); FLUSH LOGS; +### assertion: the slave replicated event successfully and tables match +Comparing tables master:test.t1 and slave:test.t1 +DROP TABLE `t1`; === Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. stop slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; @@ -167,271 +168,39 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; -### TABLE with field_metadata_size == 250 -CREATE TABLE `t1` ( -`c1` int(11) NOT NULL AUTO_INCREMENT, -`c2` varchar(30) NOT NULL, -`c3` varchar(30) DEFAULT NULL, -`c4` varchar(30) DEFAULT NULL, -`c5` varchar(30) DEFAULT NULL, -`c6` varchar(30) DEFAULT NULL, -`c7` varchar(30) DEFAULT NULL, -`c8` varchar(30) DEFAULT NULL, -`c9` varchar(30) DEFAULT NULL, -`c10` varchar(30) DEFAULT NULL, -`c11` varchar(30) DEFAULT NULL, -`c12` varchar(30) DEFAULT NULL, -`c13` varchar(30) DEFAULT NULL, -`c14` varchar(30) DEFAULT NULL, -`c15` varchar(30) DEFAULT NULL, -`c16` varchar(30) DEFAULT NULL, -`c17` varchar(30) DEFAULT NULL, -`c18` varchar(30) DEFAULT NULL, -`c19` varchar(30) DEFAULT NULL, -`c20` varchar(30) DEFAULT NULL, -`c21` varchar(30) DEFAULT NULL, -`c22` varchar(30) DEFAULT NULL, -`c23` varchar(30) DEFAULT NULL, -`c24` varchar(30) DEFAULT NULL, -`c25` varchar(30) DEFAULT NULL, -`c26` varchar(30) DEFAULT NULL, -`c27` varchar(30) DEFAULT NULL, -`c28` varchar(30) DEFAULT NULL, -`c29` varchar(30) DEFAULT NULL, -`c30` varchar(30) DEFAULT NULL, -`c31` varchar(30) DEFAULT NULL, -`c32` varchar(30) DEFAULT NULL, -`c33` varchar(30) DEFAULT NULL, -`c34` varchar(30) DEFAULT NULL, -`c35` varchar(30) DEFAULT NULL, -`c36` varchar(30) DEFAULT NULL, -`c37` varchar(30) DEFAULT NULL, -`c38` varchar(30) DEFAULT NULL, -`c39` varchar(30) DEFAULT NULL, -`c40` varchar(30) DEFAULT NULL, -`c41` varchar(30) DEFAULT NULL, -`c42` varchar(30) DEFAULT NULL, -`c43` varchar(30) DEFAULT NULL, -`c44` varchar(30) DEFAULT NULL, -`c45` varchar(30) DEFAULT NULL, -`c46` varchar(30) DEFAULT NULL, -`c47` varchar(30) DEFAULT NULL, -`c48` varchar(30) DEFAULT NULL, -`c49` varchar(30) DEFAULT NULL, -`c50` varchar(30) DEFAULT NULL, -`c51` varchar(30) DEFAULT NULL, -`c52` varchar(30) DEFAULT NULL, -`c53` varchar(30) DEFAULT NULL, -`c54` varchar(30) DEFAULT NULL, -`c55` varchar(30) DEFAULT NULL, -`c56` varchar(30) DEFAULT NULL, -`c57` varchar(30) DEFAULT NULL, -`c58` varchar(30) DEFAULT NULL, -`c59` varchar(30) DEFAULT NULL, -`c60` varchar(30) DEFAULT NULL, -`c61` varchar(30) DEFAULT NULL, -`c62` varchar(30) DEFAULT NULL, -`c63` varchar(30) DEFAULT NULL, -`c64` varchar(30) DEFAULT NULL, -`c65` varchar(30) DEFAULT NULL, -`c66` varchar(30) DEFAULT NULL, -`c67` varchar(30) DEFAULT NULL, -`c68` varchar(30) DEFAULT NULL, -`c69` varchar(30) DEFAULT NULL, -`c70` varchar(30) DEFAULT NULL, -`c71` varchar(30) DEFAULT NULL, -`c72` varchar(30) DEFAULT NULL, -`c73` varchar(30) DEFAULT NULL, -`c74` varchar(30) DEFAULT NULL, -`c75` varchar(30) DEFAULT NULL, -`c76` varchar(30) DEFAULT NULL, -`c77` varchar(30) DEFAULT NULL, -`c78` varchar(30) DEFAULT NULL, -`c79` varchar(30) DEFAULT NULL, -`c80` varchar(30) DEFAULT NULL, -`c81` varchar(30) DEFAULT NULL, -`c82` varchar(30) DEFAULT NULL, -`c83` varchar(30) DEFAULT NULL, -`c84` varchar(30) DEFAULT NULL, -`c85` varchar(30) DEFAULT NULL, -`c86` varchar(30) DEFAULT NULL, -`c87` varchar(30) DEFAULT NULL, -`c88` varchar(30) DEFAULT NULL, -`c89` varchar(30) DEFAULT NULL, -`c90` varchar(30) DEFAULT NULL, -`c91` varchar(30) DEFAULT NULL, -`c92` varchar(30) DEFAULT NULL, -`c93` varchar(30) DEFAULT NULL, -`c94` varchar(30) DEFAULT NULL, -`c95` varchar(30) DEFAULT NULL, -`c96` varchar(30) DEFAULT NULL, -`c97` varchar(30) DEFAULT NULL, -`c98` varchar(30) DEFAULT NULL, -`c99` varchar(30) DEFAULT NULL, -`c100` varchar(30) DEFAULT NULL, -`c101` varchar(30) DEFAULT NULL, -`c102` varchar(30) DEFAULT NULL, -`c103` varchar(30) DEFAULT NULL, -`c104` varchar(30) DEFAULT NULL, -`c105` varchar(30) DEFAULT NULL, -`c106` varchar(30) DEFAULT NULL, -`c107` varchar(30) DEFAULT NULL, -`c108` varchar(30) DEFAULT NULL, -`c109` varchar(30) DEFAULT NULL, -`c110` varchar(30) DEFAULT NULL, -`c111` varchar(30) DEFAULT NULL, -`c112` varchar(30) DEFAULT NULL, -`c113` varchar(30) DEFAULT NULL, -`c114` varchar(30) DEFAULT NULL, -`c115` varchar(30) DEFAULT NULL, -`c116` varchar(30) DEFAULT NULL, -`c117` varchar(30) DEFAULT NULL, -`c118` varchar(30) DEFAULT NULL, -`c119` varchar(30) DEFAULT NULL, -`c120` varchar(30) DEFAULT NULL, -`c121` varchar(30) DEFAULT NULL, -`c122` varchar(30) DEFAULT NULL, -`c123` varchar(30) DEFAULT NULL, -`c124` varchar(30) DEFAULT NULL, -`c125` varchar(30) DEFAULT NULL, -`c126` varchar(30) DEFAULT NULL, -PRIMARY KEY (`c1`) -) ENGINE=InnoDB; -### TABLE with field_metadata_size == 251 -CREATE TABLE `t2` ( -`c1` float, -`c2` varchar(30) NOT NULL, -`c3` varchar(30) DEFAULT NULL, -`c4` varchar(30) DEFAULT NULL, -`c5` varchar(30) DEFAULT NULL, -`c6` varchar(30) DEFAULT NULL, -`c7` varchar(30) DEFAULT NULL, -`c8` varchar(30) DEFAULT NULL, -`c9` varchar(30) DEFAULT NULL, -`c10` varchar(30) DEFAULT NULL, -`c11` varchar(30) DEFAULT NULL, -`c12` varchar(30) DEFAULT NULL, -`c13` varchar(30) DEFAULT NULL, -`c14` varchar(30) DEFAULT NULL, -`c15` varchar(30) DEFAULT NULL, -`c16` varchar(30) DEFAULT NULL, -`c17` varchar(30) DEFAULT NULL, -`c18` varchar(30) DEFAULT NULL, -`c19` varchar(30) DEFAULT NULL, -`c20` varchar(30) DEFAULT NULL, -`c21` varchar(30) DEFAULT NULL, -`c22` varchar(30) DEFAULT NULL, -`c23` varchar(30) DEFAULT NULL, -`c24` varchar(30) DEFAULT NULL, -`c25` varchar(30) DEFAULT NULL, -`c26` varchar(30) DEFAULT NULL, -`c27` varchar(30) DEFAULT NULL, -`c28` varchar(30) DEFAULT NULL, -`c29` varchar(30) DEFAULT NULL, -`c30` varchar(30) DEFAULT NULL, -`c31` varchar(30) DEFAULT NULL, -`c32` varchar(30) DEFAULT NULL, -`c33` varchar(30) DEFAULT NULL, -`c34` varchar(30) DEFAULT NULL, -`c35` varchar(30) DEFAULT NULL, -`c36` varchar(30) DEFAULT NULL, -`c37` varchar(30) DEFAULT NULL, -`c38` varchar(30) DEFAULT NULL, -`c39` varchar(30) DEFAULT NULL, -`c40` varchar(30) DEFAULT NULL, -`c41` varchar(30) DEFAULT NULL, -`c42` varchar(30) DEFAULT NULL, -`c43` varchar(30) DEFAULT NULL, -`c44` varchar(30) DEFAULT NULL, -`c45` varchar(30) DEFAULT NULL, -`c46` varchar(30) DEFAULT NULL, -`c47` varchar(30) DEFAULT NULL, -`c48` varchar(30) DEFAULT NULL, -`c49` varchar(30) DEFAULT NULL, -`c50` varchar(30) DEFAULT NULL, -`c51` varchar(30) DEFAULT NULL, -`c52` varchar(30) DEFAULT NULL, -`c53` varchar(30) DEFAULT NULL, -`c54` varchar(30) DEFAULT NULL, -`c55` varchar(30) DEFAULT NULL, -`c56` varchar(30) DEFAULT NULL, -`c57` varchar(30) DEFAULT NULL, -`c58` varchar(30) DEFAULT NULL, -`c59` varchar(30) DEFAULT NULL, -`c60` varchar(30) DEFAULT NULL, -`c61` varchar(30) DEFAULT NULL, -`c62` varchar(30) DEFAULT NULL, -`c63` varchar(30) DEFAULT NULL, -`c64` varchar(30) DEFAULT NULL, -`c65` varchar(30) DEFAULT NULL, -`c66` varchar(30) DEFAULT NULL, -`c67` varchar(30) DEFAULT NULL, -`c68` varchar(30) DEFAULT NULL, -`c69` varchar(30) DEFAULT NULL, -`c70` varchar(30) DEFAULT NULL, -`c71` varchar(30) DEFAULT NULL, -`c72` varchar(30) DEFAULT NULL, -`c73` varchar(30) DEFAULT NULL, -`c74` varchar(30) DEFAULT NULL, -`c75` varchar(30) DEFAULT NULL, -`c76` varchar(30) DEFAULT NULL, -`c77` varchar(30) DEFAULT NULL, -`c78` varchar(30) DEFAULT NULL, -`c79` varchar(30) DEFAULT NULL, -`c80` varchar(30) DEFAULT NULL, -`c81` varchar(30) DEFAULT NULL, -`c82` varchar(30) DEFAULT NULL, -`c83` varchar(30) DEFAULT NULL, -`c84` varchar(30) DEFAULT NULL, -`c85` varchar(30) DEFAULT NULL, -`c86` varchar(30) DEFAULT NULL, -`c87` varchar(30) DEFAULT NULL, -`c88` varchar(30) DEFAULT NULL, -`c89` varchar(30) DEFAULT NULL, -`c90` varchar(30) DEFAULT NULL, -`c91` varchar(30) DEFAULT NULL, -`c92` varchar(30) DEFAULT NULL, -`c93` varchar(30) DEFAULT NULL, -`c94` varchar(30) DEFAULT NULL, -`c95` varchar(30) DEFAULT NULL, -`c96` varchar(30) DEFAULT NULL, -`c97` varchar(30) DEFAULT NULL, -`c98` varchar(30) DEFAULT NULL, -`c99` varchar(30) DEFAULT NULL, -`c100` varchar(30) DEFAULT NULL, -`c101` varchar(30) DEFAULT NULL, -`c102` varchar(30) DEFAULT NULL, -`c103` varchar(30) DEFAULT NULL, -`c104` varchar(30) DEFAULT NULL, -`c105` varchar(30) DEFAULT NULL, -`c106` varchar(30) DEFAULT NULL, -`c107` varchar(30) DEFAULT NULL, -`c108` varchar(30) DEFAULT NULL, -`c109` varchar(30) DEFAULT NULL, -`c110` varchar(30) DEFAULT NULL, -`c111` varchar(30) DEFAULT NULL, -`c112` varchar(30) DEFAULT NULL, -`c113` varchar(30) DEFAULT NULL, -`c114` varchar(30) DEFAULT NULL, -`c115` varchar(30) DEFAULT NULL, -`c116` varchar(30) DEFAULT NULL, -`c117` varchar(30) DEFAULT NULL, -`c118` varchar(30) DEFAULT NULL, -`c119` varchar(30) DEFAULT NULL, -`c120` varchar(30) DEFAULT NULL, -`c121` varchar(30) DEFAULT NULL, -`c122` varchar(30) DEFAULT NULL, -`c123` varchar(30) DEFAULT NULL, -`c124` varchar(30) DEFAULT NULL, -`c125` varchar(30) DEFAULT NULL, -`c126` varchar(30) DEFAULT NULL, -PRIMARY KEY (`c1`) -) ENGINE=InnoDB; -LOCK TABLES `t1` WRITE; -INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); -LOCK TABLES `t2` WRITE; -INSERT INTO `t2` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); -DROP TABLE `t1`; -DROP TABLE `t2`; +### action: generating several tables with different metadata +### sizes (resorting to perl) +### testing table with 249 field metadata size. +### testing table with 250 field metadata size. +### testing table with 251 field metadata size. +### testing table with 252 field metadata size. +### testing table with 253 field metadata size. +### testing table with 254 field metadata size. +### testing table with 255 field metadata size. +### testing table with 256 field metadata size. +### testing table with 257 field metadata size. +### testing table with 258 field metadata size. FLUSH LOGS; -=== Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. +### assertion: the slave replicated event successfully and tables match for t10 +Comparing tables master:test.t10 and slave:test.t10 +### assertion: the slave replicated event successfully and tables match for t9 +Comparing tables master:test.t9 and slave:test.t9 +### assertion: the slave replicated event successfully and tables match for t8 +Comparing tables master:test.t8 and slave:test.t8 +### assertion: the slave replicated event successfully and tables match for t7 +Comparing tables master:test.t7 and slave:test.t7 +### assertion: the slave replicated event successfully and tables match for t6 +Comparing tables master:test.t6 and slave:test.t6 +### assertion: the slave replicated event successfully and tables match for t5 +Comparing tables master:test.t5 and slave:test.t5 +### assertion: the slave replicated event successfully and tables match for t4 +Comparing tables master:test.t4 and slave:test.t4 +### assertion: the slave replicated event successfully and tables match for t3 +Comparing tables master:test.t3 and slave:test.t3 +### assertion: the slave replicated event successfully and tables match for t2 +Comparing tables master:test.t2 and slave:test.t2 +### assertion: the slave replicated event successfully and tables match for t1 +Comparing tables master:test.t1 and slave:test.t1 +### assertion: check that binlog is not corrupt. Using mysqlbinlog to +### detect failure. Before the patch mysqlbinlog would find +### a corrupted event, thence would fail. diff --git a/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test index 4d7ba1e0a81..022988d7ee3 100644 --- a/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test +++ b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test @@ -2,7 +2,6 @@ # BUG#42749: infinite loop writing to row based binlog - processlist shows # "freeing items" # -# BUG#50018: binlog corruption when table has many columns # # WHY # === @@ -18,8 +17,7 @@ # # Checking that the patch fixes the problem is done as follows: # -# i) tables with several fields is created (above and below a 251 -# metadata size threshold) +# i) one table with m_field_metadata sized at 290 # ii) an insert is performed; # iii) the logs are flushed; # iv) mysqlbinlog is used to check if it succeeds. @@ -29,12 +27,8 @@ # reading the event. -- source include/master-slave.inc --- source include/have_log_bin.inc -- source include/have_innodb.inc -- source include/have_binlog_format_row.inc --- connection default - -RESET MASTER; -- disable_warnings DROP TABLE IF EXISTS `t1`; @@ -192,13 +186,20 @@ CREATE TABLE `t1` ( ) ENGINE=InnoDB; LOCK TABLES `t1` WRITE; +INSERT INTO `t1`(c2) VALUES ('1'); +FLUSH LOGS; -INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); +-- sync_slave_with_master +-- connection master + +-- echo ### assertion: the slave replicated event successfully and tables match +-- let $diff_table_1=master:test.t1 +-- let $diff_table_2=slave:test.t1 +-- source include/diff_tables.inc DROP TABLE `t1`; -FLUSH LOGS; - +-- connection master -- sync_slave_with_master -- connection master @@ -208,313 +209,132 @@ FLUSH LOGS; -- exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog -- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog +############################################################# +# BUG#50018: binlog corruption when table has many columns +# +# Same test from BUG#42749, but now we generate some SQL which +# creates and inserts into tables with metadata size from 249 +# to 258. +# +# The test works as follows: +# 1. SQL for several CREATE TABLE and INSERTS are generated +# into a file. +# 2. This file is then "sourced" +# 3. The slave is synchronized with the master +# 4. FLUSH LOGS on master +# 5. Compare tables on master and slave. +# 6. run mysqlbinlog on master's binary log +# +# Steps #5 and #6 assert that binary log is not corrupted +# in both cases: when slave is replaying events and when +# mysqlbinlog is used to read the binary log + -- source include/master-slave-reset.inc -- connection master -# Create two tables one with field_metadata_size == 250 -# and another one with field_metadata_size == 252 +# Create several tables with field_metadata_size ranging +# from 249 to 258 (so that we cover 251 and 255 range). +# This should exercise the switch between using 1 or 3 +# bytes to pack m_field_metadata_size. # # Each varchar field takes up to 2 metadata bytes, see: # # Field_varstring::do_save_field_metadata (field.cc) # -# The integer field takes 0 bytes, see: -# -# Field::do_save_field_metadata (field.h) -# # The float field takes 1 byte, see: # # Field_float::do_save_field_metadata (field.cc) # -# We choose 250 and 252 which are the ones below and above -# the threshold for switching to use 1 or 3 bytes for the -# m_data_size increment. -# --- echo ### TABLE with field_metadata_size == 250 +-- let $generated_sql= $MYSQLTEST_VARDIR/tmp/b50018.sql +-- let B50018_FILE= $generated_sql -CREATE TABLE `t1` ( - `c1` int(11) NOT NULL AUTO_INCREMENT, - `c2` varchar(30) NOT NULL, - `c3` varchar(30) DEFAULT NULL, - `c4` varchar(30) DEFAULT NULL, - `c5` varchar(30) DEFAULT NULL, - `c6` varchar(30) DEFAULT NULL, - `c7` varchar(30) DEFAULT NULL, - `c8` varchar(30) DEFAULT NULL, - `c9` varchar(30) DEFAULT NULL, - `c10` varchar(30) DEFAULT NULL, - `c11` varchar(30) DEFAULT NULL, - `c12` varchar(30) DEFAULT NULL, - `c13` varchar(30) DEFAULT NULL, - `c14` varchar(30) DEFAULT NULL, - `c15` varchar(30) DEFAULT NULL, - `c16` varchar(30) DEFAULT NULL, - `c17` varchar(30) DEFAULT NULL, - `c18` varchar(30) DEFAULT NULL, - `c19` varchar(30) DEFAULT NULL, - `c20` varchar(30) DEFAULT NULL, - `c21` varchar(30) DEFAULT NULL, - `c22` varchar(30) DEFAULT NULL, - `c23` varchar(30) DEFAULT NULL, - `c24` varchar(30) DEFAULT NULL, - `c25` varchar(30) DEFAULT NULL, - `c26` varchar(30) DEFAULT NULL, - `c27` varchar(30) DEFAULT NULL, - `c28` varchar(30) DEFAULT NULL, - `c29` varchar(30) DEFAULT NULL, - `c30` varchar(30) DEFAULT NULL, - `c31` varchar(30) DEFAULT NULL, - `c32` varchar(30) DEFAULT NULL, - `c33` varchar(30) DEFAULT NULL, - `c34` varchar(30) DEFAULT NULL, - `c35` varchar(30) DEFAULT NULL, - `c36` varchar(30) DEFAULT NULL, - `c37` varchar(30) DEFAULT NULL, - `c38` varchar(30) DEFAULT NULL, - `c39` varchar(30) DEFAULT NULL, - `c40` varchar(30) DEFAULT NULL, - `c41` varchar(30) DEFAULT NULL, - `c42` varchar(30) DEFAULT NULL, - `c43` varchar(30) DEFAULT NULL, - `c44` varchar(30) DEFAULT NULL, - `c45` varchar(30) DEFAULT NULL, - `c46` varchar(30) DEFAULT NULL, - `c47` varchar(30) DEFAULT NULL, - `c48` varchar(30) DEFAULT NULL, - `c49` varchar(30) DEFAULT NULL, - `c50` varchar(30) DEFAULT NULL, - `c51` varchar(30) DEFAULT NULL, - `c52` varchar(30) DEFAULT NULL, - `c53` varchar(30) DEFAULT NULL, - `c54` varchar(30) DEFAULT NULL, - `c55` varchar(30) DEFAULT NULL, - `c56` varchar(30) DEFAULT NULL, - `c57` varchar(30) DEFAULT NULL, - `c58` varchar(30) DEFAULT NULL, - `c59` varchar(30) DEFAULT NULL, - `c60` varchar(30) DEFAULT NULL, - `c61` varchar(30) DEFAULT NULL, - `c62` varchar(30) DEFAULT NULL, - `c63` varchar(30) DEFAULT NULL, - `c64` varchar(30) DEFAULT NULL, - `c65` varchar(30) DEFAULT NULL, - `c66` varchar(30) DEFAULT NULL, - `c67` varchar(30) DEFAULT NULL, - `c68` varchar(30) DEFAULT NULL, - `c69` varchar(30) DEFAULT NULL, - `c70` varchar(30) DEFAULT NULL, - `c71` varchar(30) DEFAULT NULL, - `c72` varchar(30) DEFAULT NULL, - `c73` varchar(30) DEFAULT NULL, - `c74` varchar(30) DEFAULT NULL, - `c75` varchar(30) DEFAULT NULL, - `c76` varchar(30) DEFAULT NULL, - `c77` varchar(30) DEFAULT NULL, - `c78` varchar(30) DEFAULT NULL, - `c79` varchar(30) DEFAULT NULL, - `c80` varchar(30) DEFAULT NULL, - `c81` varchar(30) DEFAULT NULL, - `c82` varchar(30) DEFAULT NULL, - `c83` varchar(30) DEFAULT NULL, - `c84` varchar(30) DEFAULT NULL, - `c85` varchar(30) DEFAULT NULL, - `c86` varchar(30) DEFAULT NULL, - `c87` varchar(30) DEFAULT NULL, - `c88` varchar(30) DEFAULT NULL, - `c89` varchar(30) DEFAULT NULL, - `c90` varchar(30) DEFAULT NULL, - `c91` varchar(30) DEFAULT NULL, - `c92` varchar(30) DEFAULT NULL, - `c93` varchar(30) DEFAULT NULL, - `c94` varchar(30) DEFAULT NULL, - `c95` varchar(30) DEFAULT NULL, - `c96` varchar(30) DEFAULT NULL, - `c97` varchar(30) DEFAULT NULL, - `c98` varchar(30) DEFAULT NULL, - `c99` varchar(30) DEFAULT NULL, - `c100` varchar(30) DEFAULT NULL, - `c101` varchar(30) DEFAULT NULL, - `c102` varchar(30) DEFAULT NULL, - `c103` varchar(30) DEFAULT NULL, - `c104` varchar(30) DEFAULT NULL, - `c105` varchar(30) DEFAULT NULL, - `c106` varchar(30) DEFAULT NULL, - `c107` varchar(30) DEFAULT NULL, - `c108` varchar(30) DEFAULT NULL, - `c109` varchar(30) DEFAULT NULL, - `c110` varchar(30) DEFAULT NULL, - `c111` varchar(30) DEFAULT NULL, - `c112` varchar(30) DEFAULT NULL, - `c113` varchar(30) DEFAULT NULL, - `c114` varchar(30) DEFAULT NULL, - `c115` varchar(30) DEFAULT NULL, - `c116` varchar(30) DEFAULT NULL, - `c117` varchar(30) DEFAULT NULL, - `c118` varchar(30) DEFAULT NULL, - `c119` varchar(30) DEFAULT NULL, - `c120` varchar(30) DEFAULT NULL, - `c121` varchar(30) DEFAULT NULL, - `c122` varchar(30) DEFAULT NULL, - `c123` varchar(30) DEFAULT NULL, - `c124` varchar(30) DEFAULT NULL, - `c125` varchar(30) DEFAULT NULL, - `c126` varchar(30) DEFAULT NULL, - PRIMARY KEY (`c1`) -) ENGINE=InnoDB; +-- echo ### action: generating several tables with different metadata +-- echo ### sizes (resorting to perl) +-- perl +my $file= $ENV{'B50018_FILE'}; +open(FILE, ">", "$file") or die "Unable to open bug 50018 generated SQL file: $!" ; --- echo ### TABLE with field_metadata_size == 251 +my $tables= ""; +my $ntables= 10; +my $base_ncols= 124; -CREATE TABLE `t2` ( - `c1` float, - `c2` varchar(30) NOT NULL, - `c3` varchar(30) DEFAULT NULL, - `c4` varchar(30) DEFAULT NULL, - `c5` varchar(30) DEFAULT NULL, - `c6` varchar(30) DEFAULT NULL, - `c7` varchar(30) DEFAULT NULL, - `c8` varchar(30) DEFAULT NULL, - `c9` varchar(30) DEFAULT NULL, - `c10` varchar(30) DEFAULT NULL, - `c11` varchar(30) DEFAULT NULL, - `c12` varchar(30) DEFAULT NULL, - `c13` varchar(30) DEFAULT NULL, - `c14` varchar(30) DEFAULT NULL, - `c15` varchar(30) DEFAULT NULL, - `c16` varchar(30) DEFAULT NULL, - `c17` varchar(30) DEFAULT NULL, - `c18` varchar(30) DEFAULT NULL, - `c19` varchar(30) DEFAULT NULL, - `c20` varchar(30) DEFAULT NULL, - `c21` varchar(30) DEFAULT NULL, - `c22` varchar(30) DEFAULT NULL, - `c23` varchar(30) DEFAULT NULL, - `c24` varchar(30) DEFAULT NULL, - `c25` varchar(30) DEFAULT NULL, - `c26` varchar(30) DEFAULT NULL, - `c27` varchar(30) DEFAULT NULL, - `c28` varchar(30) DEFAULT NULL, - `c29` varchar(30) DEFAULT NULL, - `c30` varchar(30) DEFAULT NULL, - `c31` varchar(30) DEFAULT NULL, - `c32` varchar(30) DEFAULT NULL, - `c33` varchar(30) DEFAULT NULL, - `c34` varchar(30) DEFAULT NULL, - `c35` varchar(30) DEFAULT NULL, - `c36` varchar(30) DEFAULT NULL, - `c37` varchar(30) DEFAULT NULL, - `c38` varchar(30) DEFAULT NULL, - `c39` varchar(30) DEFAULT NULL, - `c40` varchar(30) DEFAULT NULL, - `c41` varchar(30) DEFAULT NULL, - `c42` varchar(30) DEFAULT NULL, - `c43` varchar(30) DEFAULT NULL, - `c44` varchar(30) DEFAULT NULL, - `c45` varchar(30) DEFAULT NULL, - `c46` varchar(30) DEFAULT NULL, - `c47` varchar(30) DEFAULT NULL, - `c48` varchar(30) DEFAULT NULL, - `c49` varchar(30) DEFAULT NULL, - `c50` varchar(30) DEFAULT NULL, - `c51` varchar(30) DEFAULT NULL, - `c52` varchar(30) DEFAULT NULL, - `c53` varchar(30) DEFAULT NULL, - `c54` varchar(30) DEFAULT NULL, - `c55` varchar(30) DEFAULT NULL, - `c56` varchar(30) DEFAULT NULL, - `c57` varchar(30) DEFAULT NULL, - `c58` varchar(30) DEFAULT NULL, - `c59` varchar(30) DEFAULT NULL, - `c60` varchar(30) DEFAULT NULL, - `c61` varchar(30) DEFAULT NULL, - `c62` varchar(30) DEFAULT NULL, - `c63` varchar(30) DEFAULT NULL, - `c64` varchar(30) DEFAULT NULL, - `c65` varchar(30) DEFAULT NULL, - `c66` varchar(30) DEFAULT NULL, - `c67` varchar(30) DEFAULT NULL, - `c68` varchar(30) DEFAULT NULL, - `c69` varchar(30) DEFAULT NULL, - `c70` varchar(30) DEFAULT NULL, - `c71` varchar(30) DEFAULT NULL, - `c72` varchar(30) DEFAULT NULL, - `c73` varchar(30) DEFAULT NULL, - `c74` varchar(30) DEFAULT NULL, - `c75` varchar(30) DEFAULT NULL, - `c76` varchar(30) DEFAULT NULL, - `c77` varchar(30) DEFAULT NULL, - `c78` varchar(30) DEFAULT NULL, - `c79` varchar(30) DEFAULT NULL, - `c80` varchar(30) DEFAULT NULL, - `c81` varchar(30) DEFAULT NULL, - `c82` varchar(30) DEFAULT NULL, - `c83` varchar(30) DEFAULT NULL, - `c84` varchar(30) DEFAULT NULL, - `c85` varchar(30) DEFAULT NULL, - `c86` varchar(30) DEFAULT NULL, - `c87` varchar(30) DEFAULT NULL, - `c88` varchar(30) DEFAULT NULL, - `c89` varchar(30) DEFAULT NULL, - `c90` varchar(30) DEFAULT NULL, - `c91` varchar(30) DEFAULT NULL, - `c92` varchar(30) DEFAULT NULL, - `c93` varchar(30) DEFAULT NULL, - `c94` varchar(30) DEFAULT NULL, - `c95` varchar(30) DEFAULT NULL, - `c96` varchar(30) DEFAULT NULL, - `c97` varchar(30) DEFAULT NULL, - `c98` varchar(30) DEFAULT NULL, - `c99` varchar(30) DEFAULT NULL, - `c100` varchar(30) DEFAULT NULL, - `c101` varchar(30) DEFAULT NULL, - `c102` varchar(30) DEFAULT NULL, - `c103` varchar(30) DEFAULT NULL, - `c104` varchar(30) DEFAULT NULL, - `c105` varchar(30) DEFAULT NULL, - `c106` varchar(30) DEFAULT NULL, - `c107` varchar(30) DEFAULT NULL, - `c108` varchar(30) DEFAULT NULL, - `c109` varchar(30) DEFAULT NULL, - `c110` varchar(30) DEFAULT NULL, - `c111` varchar(30) DEFAULT NULL, - `c112` varchar(30) DEFAULT NULL, - `c113` varchar(30) DEFAULT NULL, - `c114` varchar(30) DEFAULT NULL, - `c115` varchar(30) DEFAULT NULL, - `c116` varchar(30) DEFAULT NULL, - `c117` varchar(30) DEFAULT NULL, - `c118` varchar(30) DEFAULT NULL, - `c119` varchar(30) DEFAULT NULL, - `c120` varchar(30) DEFAULT NULL, - `c121` varchar(30) DEFAULT NULL, - `c122` varchar(30) DEFAULT NULL, - `c123` varchar(30) DEFAULT NULL, - `c124` varchar(30) DEFAULT NULL, - `c125` varchar(30) DEFAULT NULL, - `c126` varchar(30) DEFAULT NULL, - PRIMARY KEY (`c1`) -) ENGINE=InnoDB; +for my $i (1..$ntables) +{ + my $ncols= $base_ncols + $i; + my $metadata_size= $ncols_variable * 2 + 1; -LOCK TABLES `t1` WRITE; -INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); + print FILE "-- echo ### testing table with " . ($base_ncols*2 + $i) . " field metadata size.\n"; + print FILE "CREATE TABLE t$i (\n"; + for my $n (1..$base_ncols) + { + print FILE "c$n VARCHAR(30) NOT NULL DEFAULT 'BUG#50018',\n"; + } + for my $n (1..$i) + { + print FILE "c" . ($base_ncols+$n) . " FLOAT NOT NULL DEFAULT 0"; + if ($n < $i) + { + print FILE ",\n"; + } + } -LOCK TABLES `t2` WRITE; -INSERT INTO `t2` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); + print FILE ") Engine=InnoDB;\n"; -DROP TABLE `t1`; -DROP TABLE `t2`; + $tables.= " t$i WRITE"; + if ($i < $ntables) + { + $tables .=","; + } + + print FILE "LOCK TABLES t$i WRITE;\n"; + print FILE "INSERT INTO t$i(c". ($base_ncols+1) . ") VALUES (50018);\n"; +} + +close(FILE); + +EOF + +## we don't need this in the result file +## however, for debugging purposes you +## may want to reactivate query logging +-- disable_query_log +-- source $generated_sql +UNLOCK TABLES; +-- enable_query_log + +-- sync_slave_with_master +-- connection master FLUSH LOGS; --- sync_slave_with_master +-- let $ntables=10 +while($ntables) +{ + -- echo ### assertion: the slave replicated event successfully and tables match for t$ntables + -- let $diff_table_1=master:test.t$ntables + -- let $diff_table_2=slave:test.t$ntables + -- source include/diff_tables.inc --- connection master + -- connection master + -- disable_query_log + -- eval DROP TABLE t$ntables + -- enable_query_log + -- sync_slave_with_master + -- connection master --- echo === Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. + -- dec $ntables +} +-- echo ### assertion: check that binlog is not corrupt. Using mysqlbinlog to +-- echo ### detect failure. Before the patch mysqlbinlog would find +-- echo ### a corrupted event, thence would fail. -- let $MYSQLD_DATADIR= `SELECT @@datadir`; --- exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog --- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog +-- exec $MYSQL_BINLOG -v --hex $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog +## clean up +## For debugging purposes you might want not to remove these +-- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog +-- remove_file $generated_sql -- source include/master-slave-end.inc From c1043021c81a4394b5aa9961d7106c437275b040 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Jan 2010 13:42:23 +0800 Subject: [PATCH 092/157] BUG #28421 Infinite loop on slave relay logs Manually deleteing one or more entries from 'master-bin.index', will cause master infinitely loop to send one binlog file. When starting a dump session, master opens index file and search the binlog file which is being requested by the slave. The position of the binlog file in the index file is recorded. it will be used to find the next binlog file when current binlog file has dumped completely. As only the position is used, it may not get the correct file if some entries has been removed manually from the index file. the master will reopen the current binlog file which has been dump completely and redump it if it can not get the next binlog file's name from index file. It obviously is a logical error. Even though it is allowed to manually change index file, but it is not recommended. so after this patch, master sends a fatal error to slave and close the dump session if a new binlog file has been generated and master can not get it from the index file. --- mysql-test/include/truncate_file.inc | 16 ++++ .../rpl/r/rpl_manual_change_index_file.result | 25 ++++++ .../rpl/t/rpl_manual_change_index_file.test | 85 +++++++++++++++++++ sql/sql_repl.cc | 9 +- 4 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 mysql-test/include/truncate_file.inc create mode 100644 mysql-test/suite/rpl/r/rpl_manual_change_index_file.result create mode 100644 mysql-test/suite/rpl/t/rpl_manual_change_index_file.test diff --git a/mysql-test/include/truncate_file.inc b/mysql-test/include/truncate_file.inc new file mode 100644 index 00000000000..c82108681bd --- /dev/null +++ b/mysql-test/include/truncate_file.inc @@ -0,0 +1,16 @@ +# truncate a giving file, all contents of the file are be cleared + +if (`SELECT 'x$file' = 'x'`) +{ + --echo Please assign a file name to $file!! + exit; +} + +let TRUNCATE_FILE= $file; + +perl; +use Env; +Env::import('TRUNCATE_FILE'); +open FILE, '>', $TRUNCATE_FILE || die "Can not open file $file"; +close FILE; +EOF diff --git a/mysql-test/suite/rpl/r/rpl_manual_change_index_file.result b/mysql-test/suite/rpl/r/rpl_manual_change_index_file.result new file mode 100644 index 00000000000..9061abca477 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_manual_change_index_file.result @@ -0,0 +1,25 @@ +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; +FLUSH LOGS; +CREATE TABLE t1(c1 INT); +FLUSH LOGS; +call mtr.add_suppression('Got fatal error 1236 from master when reading data from binary log: .*could not find next log'); +Last_IO_Error +Got fatal error 1236 from master when reading data from binary log: 'could not find next log' +CREATE TABLE t2(c1 INT); +FLUSH LOGS; +CREATE TABLE t3(c1 INT); +FLUSH LOGS; +CREATE TABLE t4(c1 INT); +START SLAVE IO_THREAD; +SHOW TABLES; +Tables_in_test +t1 +t2 +t3 +t4 +DROP TABLE t1, t2, t3, t4; diff --git a/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test new file mode 100644 index 00000000000..ba3dbd174f4 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test @@ -0,0 +1,85 @@ +source include/master-slave.inc; + +# +# BUG#28421 Infinite loop on slave relay logs +# +# That, manually deleteing one or more entries from 'master-bin.index', will +# cause master infinitely loop to send one binlog file. +# +# Manually changing index file is a illegal action, so when this happen, we +# send a fatal error to slave and close the dump session. + +FLUSH LOGS; +# Now, 2 entries in index file. +# ./master-bin.000001 +# ./master-bin.000002 + +CREATE TABLE t1(c1 INT); +# Now, the current dump file(master-bin.000002) is the second line of index +# file +sync_slave_with_master; +# Now, all events has been replicate to slave. As current dump file +# (master-bin.000002) is the last binlog file, so master is waiting for new +# events. + +connection master; +# Delete './master-bin.000001' from index file. +let $MYSQLD_DATADIR= `SELECT @@DATADIR`; +#remove_file $MYSQLD_DATADIR/master-bin.index; +let $file= $MYSQLD_DATADIR/master-bin.index; +source include/truncate_file.inc; + +if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) NOT IN ('Win32', 'Win64', 'Windows')`) +{ +append_file $MYSQLD_DATADIR/master-bin.index; +./master-bin.000002 +EOF +sleep 0.00000001; +} + +if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) IN ('Win32', 'Win64', 'Windows')`) +{ +append_file $MYSQLD_DATADIR/master-bin.index; +.\master-bin.000002 +EOF +sleep 0.00000001; +} + +# Now, only 1 entry in index file. +# ./master-bin.000002 + +# Generate master-bin.000003, but it is in the second line. +FLUSH LOGS; +# Now, 2 entries in index file. +# ./master-bin.000002 +# ./master-bin.000003 + +# Now, master know that new binlog file(master-bin.000003) has been generated. +# It expects that the new binlog file is in third line of index file, but +# there is no third line in index file. It is so strange that master sends an +# error to slave. +call mtr.add_suppression('Got fatal error 1236 from master when reading data from binary log: .*could not find next log'); +connection slave; +source include/wait_for_slave_io_to_stop.inc; +let $last_error= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1); +echo Last_IO_Error; +echo $last_error; + +connection master; +CREATE TABLE t2(c1 INT); +FLUSH LOGS; +CREATE TABLE t3(c1 INT); +FLUSH LOGS; +CREATE TABLE t4(c1 INT); + +connection slave; +START SLAVE IO_THREAD; +source include/wait_for_slave_io_to_start.inc; + +connection master; +sync_slave_with_master; +SHOW TABLES; + +connection master; +DROP TABLE t1, t2, t3, t4; +source include/master-slave-end.inc; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index b8f2e1e39bf..de038f8dc2c 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -711,11 +711,14 @@ impossible position"; thd_proc_info(thd, "Finished reading one binlog; switching to next binlog"); switch (mysql_bin_log.find_next_log(&linfo, 1)) { - case LOG_INFO_EOF: - loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK); - break; case 0: break; + case LOG_INFO_EOF: + if (mysql_bin_log.is_active(log_file_name)) + { + loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK); + break; + } default: errmsg = "could not find next log"; my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; From 4ae5679f4720c8c4a5d04b0c4c4661cad1076b2c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Jan 2010 23:32:40 +0800 Subject: [PATCH 093/157] Postfix Recover the right contents of the index file at the end of the test case. --- .../rpl/t/rpl_manual_change_index_file.test | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test index ba3dbd174f4..ecdf10ac2c2 100644 --- a/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test +++ b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test @@ -25,7 +25,6 @@ sync_slave_with_master; connection master; # Delete './master-bin.000001' from index file. let $MYSQLD_DATADIR= `SELECT @@DATADIR`; -#remove_file $MYSQLD_DATADIR/master-bin.index; let $file= $MYSQLD_DATADIR/master-bin.index; source include/truncate_file.inc; @@ -45,8 +44,7 @@ EOF sleep 0.00000001; } -# Now, only 1 entry in index file. -# ./master-bin.000002 +# Now, only 1 entry in index file. ./master-bin.000002 # Generate master-bin.000003, but it is in the second line. FLUSH LOGS; @@ -66,6 +64,29 @@ echo Last_IO_Error; echo $last_error; connection master; + +source include/truncate_file.inc; + +if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) NOT IN ('Win32', 'Win64', 'Windows')`) +{ +append_file $MYSQLD_DATADIR/master-bin.index; +./master-bin.000001 +./master-bin.000002 +./master-bin.000003 +EOF +sleep 0.00000001; +} + +if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) IN ('Win32', 'Win64', 'Windows')`) +{ +append_file $MYSQLD_DATADIR/master-bin.index; +.\master-bin.000001 +.\master-bin.000002 +.\master-bin.000003 +EOF +sleep 0.00000001; +} + CREATE TABLE t2(c1 INT); FLUSH LOGS; CREATE TABLE t3(c1 INT); From 107f34ed77aad27b1fca24aaf048d1cbb28978b2 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Mon, 11 Jan 2010 18:21:22 +0400 Subject: [PATCH 094/157] Bug #49955: ld error message: undefined reference to `strmov_overlapp' 32bit builds with the --enable-assembler flag (enabled by default) fail with an error message: undefined reference to `strmov_overlapp'. Since the fix for bug 48866 we use a home-grown strmov function instead of the ctpcpy function, but the source file for this function was missed in the Makefile.am. The strings/Makefile.am file has been modified to include strmov.c file into ASSEMBLER_x86 and ASSEMBLER_sparc32 sections. strings/Makefile.am: Bug #49955: ld error message: undefined reference to `strmov_overlapp' The strings/Makefile.am file has been modified to include strmov.c file into ASSEMBLER_x86 and ASSEMBLER_sparc32 sections. --- strings/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/strings/Makefile.am b/strings/Makefile.am index f0d6585dee4..c4712792c69 100644 --- a/strings/Makefile.am +++ b/strings/Makefile.am @@ -21,13 +21,13 @@ pkglib_LIBRARIES = libmystrings.a # Exact one of ASSEMBLER_X if ASSEMBLER_x86 ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s -CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c +CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c strmov.c else if ASSEMBLER_sparc32 # These file MUST all be on the same line!! Otherwise automake # generats a very broken makefile ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s -CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c +CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c strmov.c else #no assembler ASRCS = From 3c9322e73f5b994b7ec13ed73e99ce4bc94694b8 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Mon, 11 Jan 2010 19:23:36 +0100 Subject: [PATCH 095/157] Implement the change of RPM versioning and file naming: - "release" starts from 1 - "level" ("m2", "rc", ...) is included in the RPM version. --- support-files/Makefile.am | 3 ++- support-files/mysql.spec.sh | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/support-files/Makefile.am b/support-files/Makefile.am index 77eddea3227..c78f08a39b3 100644 --- a/support-files/Makefile.am +++ b/support-files/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2000-2001, 2003-2006 MySQL AB +# Copyright (C) 2000-2006 MySQL AB, 2008-2010 Sun Microsystems, Inc. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public @@ -119,6 +119,7 @@ SUFFIXES = .sh -e 's!@''SHARED_LIB_VERSION''@!@SHARED_LIB_VERSION@!' \ -e 's!@''MYSQL_BASE_VERSION''@!@MYSQL_BASE_VERSION@!' \ -e 's!@''MYSQL_NO_DASH_VERSION''@!@MYSQL_NO_DASH_VERSION@!' \ + -e 's!@''MYSQL_U_SCORE_VERSION''@!@MYSQL_U_SCORE_VERSION@!' \ -e 's!@''MYSQL_COPYRIGHT_YEAR''@!@MYSQL_COPYRIGHT_YEAR@!' \ -e 's!@''MYSQL_TCP_PORT''@!@MYSQL_TCP_PORT@!' \ -e 's!@''PERL_DBI_VERSION''@!@PERL_DBI_VERSION@!' \ diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 8209c4560c6..6c586d21a3c 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -1,4 +1,4 @@ -# Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +# Copyright 2000-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc. # # 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 @@ -51,9 +51,9 @@ %{!?_with_cluster:%define CLUSTER_BUILD 0} %if %{STATIC_BUILD} -%define release 0 +%define release 1 %else -%define release 0.glibc23 +%define release 1.glibc23 %endif %define mysql_license GPL %define mysqld_user mysql @@ -87,7 +87,7 @@ Name: MySQL Summary: MySQL: a very fast and reliable SQL database server Group: Applications/Databases -Version: @MYSQL_NO_DASH_VERSION@ +Version: @MYSQL_U_SCORE_VERSION@ Release: %{release} License: Copyright 2000-2008 MySQL AB, @MYSQL_COPYRIGHT_YEAR@ Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Under %{mysql_license} license as shown in the Description field. Source: http://www.mysql.com/Downloads/MySQL-@MYSQL_BASE_VERSION@/mysql-%{mysql_version}.tar.gz @@ -882,6 +882,12 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Mon Jan 11 2010 Joerg Bruehe + +- Change RPM file naming: + - Suffix like "-m2", "-rc" becomes part of version as "_m2", "_rc". + - Release counts from 1, not 0. + * Mon Aug 24 2009 Jonathan Perkin - Add conditionals for bundled zlib and innodb plugin From 71465af9d40b85c38cebdeed393925302003785b Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Tue, 12 Jan 2010 12:41:18 +0100 Subject: [PATCH 096/157] Implement the change of RPM versioning and file naming: - "release" starts from 1 - "level" ("m2", "rc", ...) is included in the RPM version. --- configure.in | 13 ++++++++----- support-files/Makefile.am | 3 ++- support-files/mysql.spec.sh | 14 ++++++++++---- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/configure.in b/configure.in index b206dfbd079..405ebddadbe 100644 --- a/configure.in +++ b/configure.in @@ -30,12 +30,14 @@ NDB_VERSION_STATUS="" # Remember that regexps needs to quote [ and ] since this is run through m4 # We take some made up examples # -# VERSION 5.1.40sp1-alpha 5.0.34a -# MYSQL_NO_DASH_VERSION 5.1.40sp1 5.0.34a -# MYSQL_NUMERIC_VERSION 5.1.40 5.0.34 -# MYSQL_BASE_VERSION 5.1 5.0 -# MYSQL_VERSION_ID 50140 50034 +# VERSION 5.1.40sp1-alpha 5.0.34a 5.5.1-m2 +# MYSQL_U_SCORE_VERSION 5.1.40sp1_alpha 5.0.34a 5.5.1_m2 +# MYSQL_NO_DASH_VERSION 5.1.40sp1 5.0.34a 5.5.1 +# MYSQL_NUMERIC_VERSION 5.1.40 5.0.34 5.5.1 +# MYSQL_BASE_VERSION 5.1 5.0 5.5 +# MYSQL_VERSION_ID 50140 50034 50501 # +MYSQL_U_SCORE_VERSION=`echo $VERSION | sed -e "s|-|_|"` MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|-.*$||"` MYSQL_NUMERIC_VERSION=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|[[a-z]][[a-z0-9]]*$||"` MYSQL_BASE_VERSION=`echo $MYSQL_NUMERIC_VERSION | sed -e "s|\.[[^.]]*$||"` @@ -78,6 +80,7 @@ romanian russian serbian slovak spanish swedish ukrainian" ##### ##### +AC_SUBST(MYSQL_U_SCORE_VERSION) AC_SUBST(MYSQL_NO_DASH_VERSION) AC_SUBST(MYSQL_BASE_VERSION) AC_SUBST(MYSQL_VERSION_ID) diff --git a/support-files/Makefile.am b/support-files/Makefile.am index b9d6fde742a..4cb8bb4645d 100644 --- a/support-files/Makefile.am +++ b/support-files/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2000-2001, 2003-2006 MySQL AB +# Copyright (C) 2000-2006 MySQL AB, 2008-2010 Sun Microsystems, Inc. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public @@ -104,6 +104,7 @@ SUFFIXES = .sh -e 's!@''SHARED_LIB_VERSION''@!@SHARED_LIB_VERSION@!' \ -e 's!@''MYSQL_BASE_VERSION''@!@MYSQL_BASE_VERSION@!' \ -e 's!@''MYSQL_NO_DASH_VERSION''@!@MYSQL_NO_DASH_VERSION@!' \ + -e 's!@''MYSQL_U_SCORE_VERSION''@!@MYSQL_U_SCORE_VERSION@!' \ -e 's!@''MYSQL_TCP_PORT''@!@MYSQL_TCP_PORT@!' \ -e 's!@''PERL_DBI_VERSION''@!@PERL_DBI_VERSION@!' \ -e 's!@''PERL_DBD_VERSION''@!@PERL_DBD_VERSION@!' \ diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 584c0abc777..98f715da94d 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -1,4 +1,4 @@ -# Copyright (C) 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +# Copyright (C) 2000-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc. # # 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 @@ -28,9 +28,9 @@ %{!?_with_yassl:%define YASSL_BUILD 0} %if %{STATIC_BUILD} -%define release 0 +%define release 1 %else -%define release 0.glibc23 +%define release 1.glibc23 %endif %define license GPL %define mysqld_user mysql @@ -64,7 +64,7 @@ Name: MySQL Summary: MySQL: a very fast and reliable SQL database server Group: Applications/Databases -Version: @MYSQL_NO_DASH_VERSION@ +Version: @MYSQL_U_SCORE_VERSION@ Release: %{release} License: %{license} Source: http://www.mysql.com/Downloads/MySQL-@MYSQL_BASE_VERSION@/mysql-%{mysql_version}.tar.gz @@ -818,6 +818,12 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Mon Jan 11 2010 Joerg Bruehe + +- Change RPM file naming: + - Suffix like "-m2", "-rc" becomes part of version as "_m2", "_rc". + - Release counts from 1, not 0. + * Fri Nov 07 2008 Joerg Bruehe - Correct yesterday's fix, so that it also works for the last flag. From c8b5804f295ea109f56f29de8c350133f9070a6a Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Tue, 12 Jan 2010 15:16:26 +0100 Subject: [PATCH 097/157] Bug#48157: crash in Item_field::used_tables MySQL handles the join syntax "JOIN ... USING( field1, ... )" and natural joins by building the same parse tree as a corresponding join with an "ON t1.field1 = t2.field1 ..." expression would produce. This parse tree was not cleaned up properly in the following scenario. If a thread tries to lock some tables and finds that the tables were dropped and re-created while waiting for the lock, it cleans up column references in the statement by means a per-statement free list. But if the statement was part of a stored procedure, column references on the stored procedure's free list weren't cleaned up and thus contained pointers to freed objects. Fixed by adding a call to clean up the current prepared statement's free list. mysql-test/r/sp_sync.result: Bug#48157: Test case mysql-test/t/sp_sync.test: Bug#48157: Test result sql/item.h: Bug#48157: Commented field. sql/sql_parse.cc: Bug#48157: Commented function. sql/sql_update.cc: Bug#48157: fix --- mysql-test/r/sp_sync.result | 23 ++++++++++++++++ mysql-test/t/sp_sync.test | 55 +++++++++++++++++++++++++++++++++++++ sql/item.h | 7 +++++ sql/sql_parse.cc | 6 ++-- sql/sql_update.cc | 6 +++- 5 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 mysql-test/r/sp_sync.result create mode 100644 mysql-test/t/sp_sync.test diff --git a/mysql-test/r/sp_sync.result b/mysql-test/r/sp_sync.result new file mode 100644 index 00000000000..afa37e70531 --- /dev/null +++ b/mysql-test/r/sp_sync.result @@ -0,0 +1,23 @@ +Tests of syncronization of stored procedure execution. +# +# Bug#48157: crash in Item_field::used_tables +# +CREATE TABLE t1 AS SELECT 1 AS a, 1 AS b; +CREATE TABLE t2 AS SELECT 1 AS a, 1 AS b; +CREATE PROCEDURE p1() +BEGIN +UPDATE t1 JOIN t2 USING( a, b ) SET t1.b = 1, t2.b = 1; +END| +LOCK TABLES t1 WRITE, t2 WRITE; +SET DEBUG_SYNC = 'multi_update_reopen_tables SIGNAL parked WAIT_FOR go'; +CALL p1(); +DROP TABLE t1, t2; +SET DEBUG_SYNC = 'now WAIT_FOR parked'; +CREATE TABLE t1 AS SELECT 1 AS a, 1 AS b; +CREATE TABLE t2 AS SELECT 1 AS a, 1 AS b; +SET DEBUG_SYNC = 'now SIGNAL go'; +# Without the DEBUG_SYNC supplied in the same patch as this test in the +# code, this test statement will hang. +DROP TABLE t1, t2; +DROP PROCEDURE p1; +SET DEBUG_SYNC = 'RESET'; diff --git a/mysql-test/t/sp_sync.test b/mysql-test/t/sp_sync.test new file mode 100644 index 00000000000..98903989cd5 --- /dev/null +++ b/mysql-test/t/sp_sync.test @@ -0,0 +1,55 @@ +--echo Tests of syncronization of stored procedure execution. + +--source include/have_debug_sync.inc + +--echo # +--echo # Bug#48157: crash in Item_field::used_tables +--echo # + +CREATE TABLE t1 AS SELECT 1 AS a, 1 AS b; +CREATE TABLE t2 AS SELECT 1 AS a, 1 AS b; + +DELIMITER |; + +CREATE PROCEDURE p1() +BEGIN + UPDATE t1 JOIN t2 USING( a, b ) SET t1.b = 1, t2.b = 1; +END| + +DELIMITER ;| + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +LOCK TABLES t1 WRITE, t2 WRITE; + +connection con2; +LET $ID= `select connection_id()`; +SET DEBUG_SYNC = 'multi_update_reopen_tables SIGNAL parked WAIT_FOR go'; +--send CALL p1() + +connection con1; +let $wait_condition= SELECT 1 FROM information_schema.processlist WHERE ID = $ID AND +state = "Locked"; +--source include/wait_condition.inc +DROP TABLE t1, t2; +SET DEBUG_SYNC = 'now WAIT_FOR parked'; +CREATE TABLE t1 AS SELECT 1 AS a, 1 AS b; +CREATE TABLE t2 AS SELECT 1 AS a, 1 AS b; +SET DEBUG_SYNC = 'now SIGNAL go'; + +connection con2; +--reap + +disconnect con1; +disconnect con2; +connection default; + +--echo # Without the DEBUG_SYNC supplied in the same patch as this test in the +--echo # code, this test statement will hang. +DROP TABLE t1, t2; +DROP PROCEDURE p1; + +SET DEBUG_SYNC = 'RESET'; + diff --git a/sql/item.h b/sql/item.h index 8f0e5874f3f..88e90924fcc 100644 --- a/sql/item.h +++ b/sql/item.h @@ -506,6 +506,13 @@ public: char * name; /* Name from select */ /* Original item name (if it was renamed)*/ char * orig_name; + /** + Intrusive list pointer for free list. If not null, points to the next + Item on some Query_arena's free list. For instance, stored procedures + have their own Query_arena's. + + @see Query_arena::free_list + */ Item *next; uint32 max_length; uint name_length; /* Length of name */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 69c9ddc7806..48743a2d48f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -615,8 +615,10 @@ void free_items(Item *item) DBUG_VOID_RETURN; } -/* This works because items are allocated with sql_alloc() */ - +/** + This works because items are allocated with sql_alloc(). + @note The function also handles null pointers (empty list). +*/ void cleanup_items(Item *item) { DBUG_ENTER("cleanup_items"); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index c988d746500..26f40c7fa9f 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -23,6 +23,7 @@ #include "sql_select.h" #include "sp_head.h" #include "sql_trigger.h" +#include "debug_sync.h" /* Return 0 if row hasn't changed */ @@ -1143,8 +1144,11 @@ reopen_tables: items from 'fields' list, so the cleanup above is necessary to. */ cleanup_items(thd->free_list); - + cleanup_items(thd->stmt_arena->free_list); close_tables_for_reopen(thd, &table_list); + + DEBUG_SYNC(thd, "multi_update_reopen_tables"); + goto reopen_tables; } From 71fd38e488d1d10210c9c5370f56d682d9884814 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Wed, 13 Jan 2010 08:16:36 +0400 Subject: [PATCH 098/157] Bug #50096: CONCAT_WS inside procedure returning wrong data Selecting of the CONCAT_WS(......) result into a user variable may return wrong data. Item_func_concat_ws::val_str contains a number of memory allocation-saving optimization tricks. After the fix for bug 46815 the control flow has been changed to a branch that is commented as "This is quite uncommon!": one of places where we are trying to concatenate strings inplace. However, that "uncommon" place didn't care about PS parameters, that have another trick in Item_sp_variable::val_str(): they use the intermediate Item_sp_variable::str_value field, where they may store a reference to an external argument's buffer. The Item_func_concat_ws::val_str function has been modified to take into account val_str functions (such as Item_sp_variable::val_str) that return a pointer to an internal Item member variable that may reference to a buffer provided. mysql-test/r/func_concat.result: Added test case for bug #50096. mysql-test/t/func_concat.test: Added test case for bug #50096. sql/item_strfunc.cc: Bug #50096: CONCAT_WS inside procedure returning wrong data The Item_func_concat_ws::val_str function has been modified to take into account val_str functions (such as Item_sp_variable::val_str) that return a pointer to an internal Item member variable that may reference to a buffer provided. --- mysql-test/r/func_concat.result | 11 +++++++++++ mysql-test/t/func_concat.test | 13 +++++++++++++ sql/item_strfunc.cc | 4 ++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/func_concat.result b/mysql-test/r/func_concat.result index 75b4888fbb2..c4c2b46c6c2 100644 --- a/mysql-test/r/func_concat.result +++ b/mysql-test/r/func_concat.result @@ -1,4 +1,5 @@ DROP TABLE IF EXISTS t1; +DROP PROCEDURE IF EXISTS p1; CREATE TABLE t1 ( number INT NOT NULL, alpha CHAR(6) NOT NULL ); INSERT INTO t1 VALUES (1413006,'idlfmv'), (1413065,'smpsfz'),(1413127,'sljrhx'),(1413304,'qerfnd'); @@ -119,4 +120,14 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL PRIMARY 102 NULL 3 Using index 1 SIMPLE t1 eq_ref PRIMARY,a PRIMARY 318 func,const,const 1 DROP TABLE t1, t2; +# +# Bug #50096: CONCAT_WS inside procedure returning wrong data +# +CREATE PROCEDURE p1(a varchar(255), b int, c int) +SET @query = CONCAT_WS(",", a, b, c); +CALL p1("abcde", "0", "1234"); +SELECT @query; +@query +abcde,0,1234 +DROP PROCEDURE p1; # End of 5.1 tests diff --git a/mysql-test/t/func_concat.test b/mysql-test/t/func_concat.test index 1c7e5823fb2..e24b4354b61 100644 --- a/mysql-test/t/func_concat.test +++ b/mysql-test/t/func_concat.test @@ -4,6 +4,7 @@ --disable_warnings DROP TABLE IF EXISTS t1; +DROP PROCEDURE IF EXISTS p1; --enable_warnings CREATE TABLE t1 ( number INT NOT NULL, alpha CHAR(6) NOT NULL ); @@ -111,4 +112,16 @@ EXPLAIN SELECT CONCAT('gui_', t2.a), t1.d FROM t2 DROP TABLE t1, t2; +--echo # +--echo # Bug #50096: CONCAT_WS inside procedure returning wrong data +--echo # + +CREATE PROCEDURE p1(a varchar(255), b int, c int) + SET @query = CONCAT_WS(",", a, b, c); + +CALL p1("abcde", "0", "1234"); +SELECT @query; + +DROP PROCEDURE p1; + --echo # End of 5.1 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index b6d3f45f4c2..ecd839d8378 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -677,8 +677,8 @@ String *Item_func_concat_ws::val_str(String *str) res->length() + sep_str->length() + res2->length()) { /* We have room in str; We can't get any errors here */ - if (str == res2) - { // This is quote uncommon! + if (str->ptr() == res2->ptr()) + { // This is quite uncommon! str->replace(0,0,*sep_str); str->replace(0,0,*res); } From 495810cd1f8ceb19e7126daa5ab92660c8f942b0 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Wed, 13 Jan 2010 09:20:45 +0400 Subject: [PATCH 099/157] Fix for bug#50227: Pre-auth buffer-overflow in mySQL through yaSSL Problem: copying issuer's (or subject's) name tags into an internal buffer from incoming stream we didn't check the buffer overflow. That may lead to memory overrun, crash etc. Fix: ensure we don't overrun the buffer. Note: there's no simple test case (exploit needed). extra/yassl/taocrypt/include/asn.hpp: Fix for bug#50227: Pre-auth buffer-overflow in mySQL through yaSSL - CertDecoder::AddTag() introduced. extra/yassl/taocrypt/src/asn.cpp: Fix for bug#50227: Pre-auth buffer-overflow in mySQL through yaSSL - copying data from incoming stream to the issuer_ or subject_ buffers ensure we don't overrun them. - code cleanup. --- extra/yassl/taocrypt/include/asn.hpp | 1 + extra/yassl/taocrypt/src/asn.cpp | 123 +++++++++++++++------------ 2 files changed, 69 insertions(+), 55 deletions(-) diff --git a/extra/yassl/taocrypt/include/asn.hpp b/extra/yassl/taocrypt/include/asn.hpp index 1c1850cb47e..168b8a8c755 100644 --- a/extra/yassl/taocrypt/include/asn.hpp +++ b/extra/yassl/taocrypt/include/asn.hpp @@ -305,6 +305,7 @@ private: bool ValidateSignature(SignerList*); bool ConfirmSignature(Source&); void GetKey(); + char* AddTag(char*, const char*, const char*, word32, word32); void GetName(NameType); void GetValidity(); void GetDate(DateType); diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp index 78200841bda..f87b466502e 100644 --- a/extra/yassl/taocrypt/src/asn.cpp +++ b/extra/yassl/taocrypt/src/asn.cpp @@ -652,6 +652,23 @@ word32 CertDecoder::GetDigest() } +char *CertDecoder::AddTag(char *ptr, const char *buf_end, + const char *tag_name, word32 tag_name_length, + word32 tag_value_length) +{ + if (ptr + tag_name_length + tag_value_length > buf_end) + return 0; + + memcpy(ptr, tag_name, tag_name_length); + ptr+= tag_name_length; + + memcpy(ptr, source_.get_current(), tag_value_length); + ptr+= tag_value_length; + + return ptr; +} + + // process NAME, either issuer or subject void CertDecoder::GetName(NameType nt) { @@ -659,11 +676,21 @@ void CertDecoder::GetName(NameType nt) SHA sha; word32 length = GetSequence(); // length of all distinguished names - assert (length < ASN_NAME_MAX); + + if (length >= ASN_NAME_MAX) + goto err; length += source_.get_index(); - char* ptr = (nt == ISSUER) ? issuer_ : subject_; - word32 idx = 0; + char *ptr, *buf_end; + + if (nt == ISSUER) { + ptr= issuer_; + buf_end= ptr + sizeof(issuer_) - 1; // 1 byte for trailing 0 + } + else { + ptr= subject_; + buf_end= ptr + sizeof(subject_) - 1; // 1 byte for trailing 0 + } while (source_.get_index() < length) { GetSet(); @@ -685,47 +712,36 @@ void CertDecoder::GetName(NameType nt) byte id = source_.next(); b = source_.next(); // strType word32 strLen = GetLength(source_); - bool copy = false; - if (id == COMMON_NAME) { - memcpy(&ptr[idx], "/CN=", 4); - idx += 4; - copy = true; - } - else if (id == SUR_NAME) { - memcpy(&ptr[idx], "/SN=", 4); - idx += 4; - copy = true; - } - else if (id == COUNTRY_NAME) { - memcpy(&ptr[idx], "/C=", 3); - idx += 3; - copy = true; - } - else if (id == LOCALITY_NAME) { - memcpy(&ptr[idx], "/L=", 3); - idx += 3; - copy = true; - } - else if (id == STATE_NAME) { - memcpy(&ptr[idx], "/ST=", 4); - idx += 4; - copy = true; - } - else if (id == ORG_NAME) { - memcpy(&ptr[idx], "/O=", 3); - idx += 3; - copy = true; - } - else if (id == ORGUNIT_NAME) { - memcpy(&ptr[idx], "/OU=", 4); - idx += 4; - copy = true; - } - - if (copy) { - memcpy(&ptr[idx], source_.get_current(), strLen); - idx += strLen; + switch (id) { + case COMMON_NAME: + if (!(ptr= AddTag(ptr, buf_end, "/CN=", 4, strLen))) + goto err; + break; + case SUR_NAME: + if (!(ptr= AddTag(ptr, buf_end, "/SN=", 4, strLen))) + goto err; + break; + case COUNTRY_NAME: + if (!(ptr= AddTag(ptr, buf_end, "/C=", 3, strLen))) + goto err; + break; + case LOCALITY_NAME: + if (!(ptr= AddTag(ptr, buf_end, "/L=", 3, strLen))) + goto err; + break; + case STATE_NAME: + if (!(ptr= AddTag(ptr, buf_end, "/ST=", 4, strLen))) + goto err; + break; + case ORG_NAME: + if (!(ptr= AddTag(ptr, buf_end, "/O=", 3, strLen))) + goto err; + break; + case ORGUNIT_NAME: + if (!(ptr= AddTag(ptr, buf_end, "/OU=", 4, strLen))) + goto err; + break; } sha.Update(source_.get_current(), strLen); @@ -739,23 +755,20 @@ void CertDecoder::GetName(NameType nt) source_.advance(oidSz + 1); word32 length = GetLength(source_); - if (email) { - memcpy(&ptr[idx], "/emailAddress=", 14); - idx += 14; - - memcpy(&ptr[idx], source_.get_current(), length); - idx += length; - } + if (email && !(ptr= AddTag(ptr, buf_end, "/emailAddress=", 14, length))) + goto err; source_.advance(length); } } - ptr[idx++] = 0; + *ptr= 0; - if (nt == ISSUER) - sha.Final(issuerHash_); - else - sha.Final(subjectHash_); + sha.Final(nt == ISSUER ? issuerHash_ : subjectHash_); + + return; + +err: + source_.SetError(CONTENT_E); } From 4dc7be62a997a0176e300878d4b5e93865606029 Mon Sep 17 00:00:00 2001 From: Sven Sandberg Date: Wed, 13 Jan 2010 10:00:03 +0100 Subject: [PATCH 100/157] BUG#49222: Mark RAND() as unsafe Problem: When RAND() is binlogged in statement mode, the seed is binlogged too, so the replication slave generates the same sequence of random numbers. This makes replication work in many cases, but not in all cases: the order of rows is not guaranteed for, e.g., UPDATE or INSERT...SELECT statements, so the row data will be different if master and slave retrieve the rows in different orders. Fix: Mark RAND() as unsafe. It will generate a warning if binlog_format=STATEMENT and switch to row-logging if binlog_format=ROW. mysql-test/extra/rpl_tests/rpl_row_func003.test: updated test case to ignore new warnings mysql-test/suite/binlog/r/binlog_unsafe.result: updated result file mysql-test/suite/binlog/t/binlog_unsafe.test: Added test for RAND(). Also clarified some old comments. mysql-test/suite/rpl/r/rpl_misc_functions.result: updated result file mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result: updated test case to ignore new warnings mysql-test/suite/rpl/r/rpl_optimize.result: updated result file mysql-test/suite/rpl/r/rpl_row_func003.result: updated result file mysql-test/suite/rpl/t/rpl_misc_functions.test: updated test case to ignore new warnings mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test: updated test case to ignore new warnings mysql-test/suite/rpl/t/rpl_optimize.test: updated test case to ignore new warnings mysql-test/suite/rpl/t/rpl_trigger.test: updated test case to ignore new warnings mysql-test/suite/rpl_ndb/r/rpl_ndb_func003.result: updated result file sql/item_create.cc: Mark RAND() unsafe. --- .../extra/rpl_tests/rpl_row_func003.test | 6 +++++ .../suite/binlog/r/binlog_unsafe.result | 3 +++ mysql-test/suite/binlog/t/binlog_unsafe.test | 24 +++++++++++-------- .../suite/rpl/r/rpl_misc_functions.result | 1 + .../r/rpl_nondeterministic_functions.result | 1 + mysql-test/suite/rpl/r/rpl_optimize.result | 1 + mysql-test/suite/rpl/r/rpl_row_func003.result | 1 + .../suite/rpl/t/rpl_misc_functions.test | 8 +++++++ .../rpl/t/rpl_nondeterministic_functions.test | 4 ++++ mysql-test/suite/rpl/t/rpl_optimize.test | 4 +++- mysql-test/suite/rpl/t/rpl_trigger.test | 2 ++ .../suite/rpl_ndb/r/rpl_ndb_func003.result | 1 + sql/item_create.cc | 10 ++++++++ 13 files changed, 55 insertions(+), 11 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_row_func003.test b/mysql-test/extra/rpl_tests/rpl_row_func003.test index 8ee2d863527..b77465de39e 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_func003.test +++ b/mysql-test/extra/rpl_tests/rpl_row_func003.test @@ -18,6 +18,8 @@ # Vs slave. # ############################################################################# +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); + # Begin clean up test section connection master; --disable_warnings @@ -43,10 +45,12 @@ RETURN tmp; END| delimiter ;| +--disable_warnings INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1()); sleep 6; INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1()); sleep 6; +--enable_warnings #Select in this test are used for debugging #select * from test.t1; @@ -56,7 +60,9 @@ sleep 6; connection master; SET AUTOCOMMIT=0; START TRANSACTION; +--disable_warnings INSERT INTO test.t1 VALUES (null,test.f1()); +--enable_warnings ROLLBACK; SET AUTOCOMMIT=1; #select * from test.t1; diff --git a/mysql-test/suite/binlog/r/binlog_unsafe.result b/mysql-test/suite/binlog/r/binlog_unsafe.result index 8bbf993a727..6b2a83c9483 100644 --- a/mysql-test/suite/binlog/r/binlog_unsafe.result +++ b/mysql-test/suite/binlog/r/binlog_unsafe.result @@ -379,6 +379,9 @@ Note 1592 Statement may not be safe to log in statement format. INSERT INTO t1 VALUES (VERSION()); Warnings: Note 1592 Statement may not be safe to log in statement format. +INSERT INTO t1 VALUES (RAND()); +Warnings: +Note 1592 Statement may not be safe to log in statement format. DELETE FROM t1; SET TIMESTAMP=1000000; INSERT INTO t1 VALUES diff --git a/mysql-test/suite/binlog/t/binlog_unsafe.test b/mysql-test/suite/binlog/t/binlog_unsafe.test index 1acb4d090ca..5e399f3e602 100644 --- a/mysql-test/suite/binlog/t/binlog_unsafe.test +++ b/mysql-test/suite/binlog/t/binlog_unsafe.test @@ -47,6 +47,8 @@ # BUG#34768: nondeterministic INSERT using LIMIT logged in stmt mode if binlog_format=mixed # BUG#41980, SBL, INSERT .. SELECT .. LIMIT = ERROR, even when @@SQL_LOG_BIN is 0 # BUG#42640: mysqld crashes when unsafe statements are executed (STRICT_TRANS_TABLES mode) +# BUG#47995: Mark user functions as unsafe +# BUG#49222: Mare RAND() unsafe # # ==== Related test cases ==== # @@ -391,6 +393,7 @@ SET @@SESSION.SQL_MODE = @save_sql_mode; # # BUG#47995: Mark user functions as unsafe +# BUG#49222: Mare RAND() unsafe # # Test that the system functions that are supposed to be marked unsafe # generate a warning. Each INSERT statement below should generate a @@ -400,27 +403,28 @@ SET @@SESSION.SQL_MODE = @save_sql_mode; CREATE TABLE t1 (a VARCHAR(1000)); INSERT INTO t1 VALUES (CURRENT_USER()); #marked unsafe before BUG#47995 INSERT INTO t1 VALUES (FOUND_ROWS()); #marked unsafe before BUG#47995 -INSERT INTO t1 VALUES (GET_LOCK('tmp', 1)); -INSERT INTO t1 VALUES (IS_FREE_LOCK('tmp')); -INSERT INTO t1 VALUES (IS_USED_LOCK('tmp')); -INSERT INTO t1 VALUES (LOAD_FILE('../../std_data/words2.dat')); #marked unsafe before BUG#47995 +INSERT INTO t1 VALUES (GET_LOCK('tmp', 1)); #marked unsafe in BUG#47995 +INSERT INTO t1 VALUES (IS_FREE_LOCK('tmp')); #marked unsafe in BUG#47995 +INSERT INTO t1 VALUES (IS_USED_LOCK('tmp')); #marked unsafe in BUG#47995 +INSERT INTO t1 VALUES (LOAD_FILE('../../std_data/words2.dat')); #marked unsafe in BUG#39701 INSERT INTO t1 VALUES (MASTER_POS_WAIT('dummy arg', 4711, 1)); -INSERT INTO t1 VALUES (RELEASE_LOCK('tmp')); +INSERT INTO t1 VALUES (RELEASE_LOCK('tmp')); #marked unsafe in BUG#47995 INSERT INTO t1 VALUES (ROW_COUNT()); #marked unsafe before BUG#47995 INSERT INTO t1 VALUES (SESSION_USER()); #marked unsafe before BUG#47995 -INSERT INTO t1 VALUES (SLEEP(1)); -INSERT INTO t1 VALUES (SYSDATE()); +INSERT INTO t1 VALUES (SLEEP(1)); #marked unsafe in BUG#47995 +INSERT INTO t1 VALUES (SYSDATE()); #marked unsafe in BUG#47995 INSERT INTO t1 VALUES (SYSTEM_USER()); #marked unsafe before BUG#47995 INSERT INTO t1 VALUES (USER()); #marked unsafe before BUG#47995 INSERT INTO t1 VALUES (UUID()); #marked unsafe before BUG#47995 INSERT INTO t1 VALUES (UUID_SHORT()); #marked unsafe before BUG#47995 -INSERT INTO t1 VALUES (VERSION()); +INSERT INTO t1 VALUES (VERSION()); #marked unsafe in BUG#47995 +INSERT INTO t1 VALUES (RAND()); #marked unsafe in BUG#49222 DELETE FROM t1; # Since we replicate the TIMESTAMP variable, functions affected by the # TIMESTAMP variable are safe to replicate. So we check that the -# following following functions depend on the TIMESTAMP variable and -# don't generate a warning. +# following following functions that depend on the TIMESTAMP variable +# are not unsafe and don't generate a warning. SET TIMESTAMP=1000000; INSERT INTO t1 VALUES diff --git a/mysql-test/suite/rpl/r/rpl_misc_functions.result b/mysql-test/suite/rpl/r/rpl_misc_functions.result index 28b777822e4..6d69235927e 100644 --- a/mysql-test/suite/rpl/r/rpl_misc_functions.result +++ b/mysql-test/suite/rpl/r/rpl_misc_functions.result @@ -4,6 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); create table t1(id int, i int, r1 int, r2 int, p varchar(100)); insert into t1 values(1, connection_id(), 0, 0, ""); insert into t1 values(2, 0, rand()*1000, rand()*1000, ""); diff --git a/mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result b/mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result index c4842a284cd..3b9b741e040 100644 --- a/mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result +++ b/mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result @@ -4,6 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); CREATE TABLE t1 (a VARCHAR(1000)); INSERT INTO t1 VALUES (CONNECTION_ID()); INSERT INTO t1 VALUES (CONNECTION_ID()); diff --git a/mysql-test/suite/rpl/r/rpl_optimize.result b/mysql-test/suite/rpl/r/rpl_optimize.result index 79891169fbc..1ae94a3ca36 100644 --- a/mysql-test/suite/rpl/r/rpl_optimize.result +++ b/mysql-test/suite/rpl/r/rpl_optimize.result @@ -4,6 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); create table t1 (a int not null auto_increment primary key, b int, key(b)); INSERT INTO t1 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); INSERT INTO t1 (a) SELECT null FROM t1; diff --git a/mysql-test/suite/rpl/r/rpl_row_func003.result b/mysql-test/suite/rpl/r/rpl_row_func003.result index a5fd46a2ce3..94d01b50ce5 100644 --- a/mysql-test/suite/rpl/r/rpl_row_func003.result +++ b/mysql-test/suite/rpl/r/rpl_row_func003.result @@ -4,6 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); DROP FUNCTION IF EXISTS test.f1; DROP TABLE IF EXISTS test.t1; CREATE TABLE test.t1 (a INT NOT NULL AUTO_INCREMENT, c CHAR(16),PRIMARY KEY(a))ENGINE=INNODB; diff --git a/mysql-test/suite/rpl/t/rpl_misc_functions.test b/mysql-test/suite/rpl/t/rpl_misc_functions.test index d2e61d579e3..b84042160cd 100644 --- a/mysql-test/suite/rpl/t/rpl_misc_functions.test +++ b/mysql-test/suite/rpl/t/rpl_misc_functions.test @@ -3,12 +3,16 @@ # source include/master-slave.inc; +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); + create table t1(id int, i int, r1 int, r2 int, p varchar(100)); insert into t1 values(1, connection_id(), 0, 0, ""); # don't put rand and password in the same query, to see if they replicate # independently # Pure rand test +--disable_warnings insert into t1 values(2, 0, rand()*1000, rand()*1000, ""); +--enable_warnings # change the rand suite on the master (we do this because otherwise password() # benefits from the fact that the above rand() is well replicated : # it picks the same sequence element, which hides a possible bug in password() replication. @@ -19,7 +23,9 @@ set sql_log_bin=1; # Pure password test insert into t1 values(3, 0, 0, 0, password('does_this_work?')); # "altogether now" +--disable_warnings insert into t1 values(4, connection_id(), rand()*1000, rand()*1000, password('does_this_still_work?')); +--enable_warnings select * into outfile 'rpl_misc_functions.outfile' from t1; let $MYSQLD_DATADIR= `select @@datadir`; sync_slave_with_master; @@ -73,11 +79,13 @@ DELIMITER ;| # Exercise the functions and procedures then compare the results on # the master to those on the slave. +--disable_warnings CALL test_replication_sp1(); CALL test_replication_sp2(); INSERT INTO t1 (col_a) VALUES (test_replication_sf()); INSERT INTO t1 (col_a) VALUES (test_replication_sf()); INSERT INTO t1 (col_a) VALUES (test_replication_sf()); +--enable_warnings --sync_slave_with_master diff --git a/mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test b/mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test index a30eb3be374..9ff2e2d081e 100644 --- a/mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test +++ b/mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test @@ -17,6 +17,8 @@ --source include/master-slave.inc +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); + CREATE TABLE t1 (a VARCHAR(1000)); # We replicate the connection_id in the query_log_event @@ -41,7 +43,9 @@ INSERT INTO t1 VALUES (UTC_TIMESTAMP()); # We replicate the random seed in a rand_log_event +--disable_warnings INSERT INTO t1 VALUES (RAND()); +--enable_warnings # We replicate the last_insert_id in an intvar_log_event INSERT INTO t1 VALUES (LAST_INSERT_ID()); diff --git a/mysql-test/suite/rpl/t/rpl_optimize.test b/mysql-test/suite/rpl/t/rpl_optimize.test index f4582ba1167..87eb9dce818 100644 --- a/mysql-test/suite/rpl/t/rpl_optimize.test +++ b/mysql-test/suite/rpl/t/rpl_optimize.test @@ -13,6 +13,8 @@ -- source include/not_ndb_default.inc -- source include/master-slave.inc +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); + create table t1 (a int not null auto_increment primary key, b int, key(b)); INSERT INTO t1 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); INSERT INTO t1 (a) SELECT null FROM t1; @@ -30,8 +32,8 @@ INSERT INTO t1 (a) SELECT null FROM t1; INSERT INTO t1 (a) SELECT null FROM t1; save_master_pos; # a few updates to force OPTIMIZE to do something -update t1 set b=(a/2*rand()); --disable_warnings +update t1 set b=(a/2*rand()); delete from t1 order by b limit 10000; --enable_warnings diff --git a/mysql-test/suite/rpl/t/rpl_trigger.test b/mysql-test/suite/rpl/t/rpl_trigger.test index 4b40fbea719..e296da01bad 100644 --- a/mysql-test/suite/rpl/t/rpl_trigger.test +++ b/mysql-test/suite/rpl/t/rpl_trigger.test @@ -40,10 +40,12 @@ insert into t3 values(100,"log",0,0,0); SET @@RAND_SEED1=658490765, @@RAND_SEED2=635893186; # Emulate that we have rows 2-9 deleted on the slave +--disable_warnings insert into t1 values(1,1,rand()),(NULL,2,rand()); insert into t2 (b) values(last_insert_id()); insert into t2 values(3,0),(NULL,0); insert into t2 values(NULL,0),(500,0); +--enable_warnings select a,b, truncate(rand_value,4) from t1; select * from t2; diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_func003.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_func003.result index ad72a3fb244..7e750f2ce2a 100644 --- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_func003.result +++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_func003.result @@ -4,6 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); DROP FUNCTION IF EXISTS test.f1; DROP TABLE IF EXISTS test.t1; CREATE TABLE test.t1 (a INT NOT NULL AUTO_INCREMENT, c CHAR(16),PRIMARY KEY(a))ENGINE=NDB; diff --git a/sql/item_create.cc b/sql/item_create.cc index 53aa8081da1..c309ccc06ca 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -4178,6 +4178,16 @@ Create_func_rand::create_native(THD *thd, LEX_STRING name, if (item_list != NULL) arg_count= item_list->elements; + /* + When RAND() is binlogged, the seed is binlogged too. So the + sequence of random numbers is the same on a replication slave as + on the master. However, if several RAND() values are inserted + into a table, the order in which the rows are modified may differ + between master and slave, because the order is undefined. Hence, + the statement is unsafe to log in statement format. + */ + thd->lex->set_stmt_unsafe(); + switch (arg_count) { case 0: { From c4ec2de72413235d5f4027758d9601b74223b01c Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 13 Jan 2010 12:43:07 +0200 Subject: [PATCH 101/157] version change --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index f044f8e62da..e613cefc614 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.1" +tree_name = "mysql-5.1-bugteam" From b3dd4d9486ca00e555823f81185fe9db83a44db5 Mon Sep 17 00:00:00 2001 From: Kristofer Pettersson Date: Wed, 13 Jan 2010 12:39:00 +0100 Subject: [PATCH 102/157] Bug#33982 debug assertion and crash reloading grant tables after sighup or kill In certain rare cases when a process was interrupted during a FLUSH PRIVILEGES operation the diagnostic area would be set to an error state but the function responsible for the operation would still signal success. This would lead to a debug assertion error later on when the server would attempt to reset the DA before sending the error message. This patch fixes the issue by assuring that reload_acl_and_cache() always fails if an error condition is raised. The second issue was that a KILL could cause a console error message which referred to a DA state without first making sure that such a state existed. This patch fixes this issue in two different palces by first checking DA state before fetching the error message. sql/sql_acl.cc: * Make sure that there is an error to print before attempting to do so. * Minor style change: change 1 to TRUE for clarity. sql/sql_parse.cc: * Always fail reload_acl_and_cache() if the query was killed. sql/sql_servers.cc: * Make sure that there is an error to print before attempting to do so. --- sql/sql_acl.cc | 15 ++++++++++----- sql/sql_parse.cc | 9 ++++++--- sql/sql_servers.cc | 10 ++++++++-- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 7d8f8ea71b3..7ba1a657578 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -310,7 +310,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) { TABLE *table; READ_RECORD read_record_info; - my_bool return_val= 1; + my_bool return_val= TRUE; bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE; char tmp_name[NAME_LEN+1]; int password_length; @@ -623,7 +623,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) init_check_host(); initialized=1; - return_val=0; + return_val= FALSE; end: thd->variables.sql_mode= old_sql_mode; @@ -674,7 +674,7 @@ my_bool acl_reload(THD *thd) DYNAMIC_ARRAY old_acl_hosts,old_acl_users,old_acl_dbs; MEM_ROOT old_mem; bool old_initialized; - my_bool return_val= 1; + my_bool return_val= TRUE; DBUG_ENTER("acl_reload"); if (thd->locked_tables) @@ -701,8 +701,13 @@ my_bool acl_reload(THD *thd) if (simple_open_n_lock_tables(thd, tables)) { - sql_print_error("Fatal error: Can't open and lock privilege tables: %s", - thd->main_da.message()); + /* + Execution might have been interrupted; only print the error message + if an error condition has been raised. + */ + if (thd->main_da.is_error()) + sql_print_error("Fatal error: Can't open and lock privilege tables: %s", + thd->main_da.message()); goto end; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 69c9ddc7806..2c466d31e7c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6787,13 +6787,13 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, thd->store_globals(); lex_start(thd); } - + if (thd) { bool reload_acl_failed= acl_reload(thd); bool reload_grants_failed= grant_reload(thd); bool reload_servers_failed= servers_reload(thd); - + if (reload_acl_failed || reload_grants_failed || reload_servers_failed) { result= 1; @@ -6949,7 +6949,10 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, if (options & REFRESH_USER_RESOURCES) reset_mqh((LEX_USER *) NULL, 0); /* purecov: inspected */ *write_to_binlog= tmp_write_to_binlog; - return result; + /* + If the query was killed then this function must fail. + */ + return result || thd->killed; } diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index f8a8dea18ff..1655426bb4a 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -241,8 +241,14 @@ bool servers_reload(THD *thd) if (simple_open_n_lock_tables(thd, tables)) { - sql_print_error("Can't open and lock privilege tables: %s", - thd->main_da.message()); + /* + Execution might have been interrupted; only print the error message + if an error condition has been raised. + */ + if (thd->main_da.is_error()) + sql_print_error("Can't open and lock privilege tables: %s", + thd->main_da.message()); + return_val= FALSE; goto end; } From 7ecd6c6d0269d1b8580f87cbdda1924d7ab0d499 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 14 Jan 2010 10:24:02 +0200 Subject: [PATCH 103/157] version change --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 557df1b1ffe..f79c1cd6319 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.0-bugteam" +tree_name = "mysql-5.0" From 5ae7b3c99634609b2890253590ccf82c5fb4f085 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 14 Jan 2010 10:49:40 +0000 Subject: [PATCH 104/157] BUG#50018: binlog corruption when table has many columns Small fix in the test case. Changed the UNLOCK tables to happen after each insert. --- mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test index 022988d7ee3..be5ebb661ca 100644 --- a/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test +++ b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test @@ -290,6 +290,7 @@ for my $i (1..$ntables) print FILE "LOCK TABLES t$i WRITE;\n"; print FILE "INSERT INTO t$i(c". ($base_ncols+1) . ") VALUES (50018);\n"; + print FILE "UNLOCK TABLES;"; } close(FILE); @@ -301,7 +302,6 @@ EOF ## may want to reactivate query logging -- disable_query_log -- source $generated_sql -UNLOCK TABLES; -- enable_query_log -- sync_slave_with_master From 32aa612819ff756b284e639de50627b3d6d7fa0d Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 14 Jan 2010 14:26:51 +0000 Subject: [PATCH 105/157] Fix for BUG#49481 and BUG#49482. BUG#49481: RBR: MyISAM and bit fields may cause slave to stop on delete: cant find record BUG#49482: RBR: Replication may break on deletes when MyISAM tables + char field are used When using MyISAM tables, despite the fact that the null bit is set for some fields, their old value is still in the row. This can cause the comparison of records to fail when the slave is doing an index or range scan. We fix this by avoiding memcmp for MyISAM tables when comparing records. Additionally, when comparing field by field, we first check if both fields are not null and if so, then we compare them. If just one field is null we return failure immediately. If both fields are null, we move on to the next field. --- .../suite/rpl/r/rpl_myisam_null_values.result | 24 +++++++++ .../suite/rpl/t/rpl_myisam_null_values.test | 53 +++++++++++++++++++ sql/log_event.cc | 39 +++++++++++++- sql/log_event_old.cc | 39 +++++++++++++- 4 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_myisam_null_values.result create mode 100644 mysql-test/suite/rpl/t/rpl_myisam_null_values.test diff --git a/mysql-test/suite/rpl/r/rpl_myisam_null_values.result b/mysql-test/suite/rpl/r/rpl_myisam_null_values.result new file mode 100644 index 00000000000..574528a8d79 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_myisam_null_values.result @@ -0,0 +1,24 @@ +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; +CREATE TABLE t1 (c1 BIT, c2 INT); +INSERT INTO `t1` VALUES ( 1, 1 ); +UPDATE t1 SET c1=NULL where c2=1; +Comparing tables master:test.t1 and slave:test.t1 +DELETE FROM t1 WHERE c2=1 LIMIT 1; +Comparing tables master:test.t1 and slave:test.t1 +DROP TABLE t1; +CREATE TABLE t1 (c1 CHAR); +INSERT INTO t1 ( c1 ) VALUES ( 'w' ) ; +SELECT * FROM t1; +c1 +w +# should trigger switch to row due to LIMIT +UPDATE t1 SET c1=NULL WHERE c1='w' LIMIT 2; +Comparing tables master:test.t1 and slave:test.t1 +DELETE FROM t1 LIMIT 2; +Comparing tables master:test.t1 and slave:test.t1 +DROP TABLE t1; diff --git a/mysql-test/suite/rpl/t/rpl_myisam_null_values.test b/mysql-test/suite/rpl/t/rpl_myisam_null_values.test new file mode 100644 index 00000000000..d9ec95fc510 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_myisam_null_values.test @@ -0,0 +1,53 @@ +# BUG#49481: RBR: MyISAM and bit fields may cause slave to stop on delete cant find record +# BUG#49482: RBR: Replication may break on deletes when MyISAM tables + char field are used + +-- source include/master-slave.inc +-- source include/have_binlog_format_mixed_or_row.inc + +-- connection master +CREATE TABLE t1 (c1 BIT, c2 INT); +INSERT INTO `t1` VALUES ( 1, 1 ); +UPDATE t1 SET c1=NULL where c2=1; +-- sync_slave_with_master + +-- let $diff_table_1=master:test.t1 +-- let $diff_table_2=slave:test.t1 +-- source include/diff_tables.inc + +-- connection master +DELETE FROM t1 WHERE c2=1 LIMIT 1; +-- sync_slave_with_master + +-- let $diff_table_1=master:test.t1 +-- let $diff_table_2=slave:test.t1 +-- source include/diff_tables.inc + +-- connection master +DROP TABLE t1; +-- sync_slave_with_master + +-- connection master + +CREATE TABLE t1 (c1 CHAR); + +INSERT INTO t1 ( c1 ) VALUES ( 'w' ) ; +SELECT * FROM t1; +-- echo # should trigger switch to row due to LIMIT +UPDATE t1 SET c1=NULL WHERE c1='w' LIMIT 2; +-- sync_slave_with_master + +-- let $diff_table_1=master:test.t1 +-- let $diff_table_2=slave:test.t1 +-- source include/diff_tables.inc + +-- connection master +DELETE FROM t1 LIMIT 2; +-- sync_slave_with_master + +-- let $diff_table_1=master:test.t1 +-- let $diff_table_2=slave:test.t1 +-- source include/diff_tables.inc + +-- connection master +DROP TABLE t1; +-- sync_slave_with_master diff --git a/sql/log_event.cc b/sql/log_event.cc index 6b21087b6aa..61f5e93e29e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -8724,6 +8724,24 @@ static bool record_compare(TABLE *table) } } + /** + Check if we are using MyISAM. + + If this is a myisam table, then we cannot do a memcmp + right away because some NULL fields can still contain + an old value in the row - they are not shown to the user + because the null bit is set, however, the contents are + not cleared. As such, plain memory comparison cannot be + assured to work. See: BUG#49482 and BUG#49481. + + On top of this, we do not store field contents for null + fields in the binlog, so this is extra important when + comparing records fetched from binlog and from storage + engine. + */ + if (table->file->ht->db_type == DB_TYPE_MYISAM) + goto record_compare_field_by_field; + if (table->s->blob_fields + table->s->varchar_fields == 0) { result= cmp_record(table,record[1]); @@ -8739,14 +8757,33 @@ static bool record_compare(TABLE *table) goto record_compare_exit; } +record_compare_field_by_field: + /* Compare updated fields */ for (Field **ptr=table->field ; *ptr ; ptr++) { - if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length)) + Field *f= *ptr; + + /* if just one of the fields is null then there is no match */ + if ((f->is_null_in_record(table->record[0])) == + !(f->is_null_in_record(table->record[1]))) { result= TRUE; goto record_compare_exit; } + + /* if both fields are not null then we can compare */ + if (!(f->is_null_in_record(table->record[0])) && + !(f->is_null_in_record(table->record[1]))) + { + if (f->cmp_binary_offset(table->s->rec_buff_length)) + { + result= TRUE; + goto record_compare_exit; + } + } + + /* if both fields are null then there is a match. compare next field */ } record_compare_exit: diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 357bc78b1cd..72a6e159535 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -351,6 +351,24 @@ static bool record_compare(TABLE *table) } } + /** + Check if we are using MyISAM. + + If this is a myisam table, then we cannot do a memcmp + right away because some NULL fields can still contain + an old value in the row - they are not shown to the user + because the null bit is set, however, the contents are + not cleared. As such, plain memory comparison cannot be + assured to work. See: BUG#49482 and BUG#49481. + + On top of this, we do not store field contents for null + fields in the binlog, so this is extra important when + comparing records fetched from binlog and from storage + engine. + */ + if (table->file->ht->db_type == DB_TYPE_MYISAM) + goto record_compare_field_by_field; + if (table->s->blob_fields + table->s->varchar_fields == 0) { result= cmp_record(table,record[1]); @@ -366,14 +384,33 @@ static bool record_compare(TABLE *table) goto record_compare_exit; } +record_compare_field_by_field: + /* Compare updated fields */ for (Field **ptr=table->field ; *ptr ; ptr++) { - if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length)) + Field *f= *ptr; + + /* if just one of the fields is null then there is no match */ + if ((f->is_null_in_record(table->record[0])) == + !(f->is_null_in_record(table->record[1]))) { result= TRUE; goto record_compare_exit; } + + /* if both fields are not null then we can compare */ + if (!(f->is_null_in_record(table->record[0])) && + !(f->is_null_in_record(table->record[1]))) + { + if (f->cmp_binary_offset(table->s->rec_buff_length)) + { + result= TRUE; + goto record_compare_exit; + } + } + + /* if both fields are null then there is a match. compare next field */ } record_compare_exit: From 85c1e30375ec7c3aa9755d44d13bd4e0281c218b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 15 Jan 2010 10:35:35 +0100 Subject: [PATCH 106/157] Raise version number after cloning 5.0.90 --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 405ebddadbe..503bf660b2c 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.90) +AM_INIT_AUTOMAKE(mysql, 5.0.91) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 @@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=90 +NDB_VERSION_BUILD=91 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? From 7a7147c5b4cca1bfd1bfbecd4883d3968526b162 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 15 Jan 2010 16:09:20 +0200 Subject: [PATCH 107/157] Bug #46175: NULL read_view and consistent read assertion The optimizer must not continue executing the current query if e.g. the storage engine reports an error. This is somewhat hard to implement with Item::val_xxx() because they do not have means to return error code. This is why we need to check the thread's error state after a call to one of the Item::val_xxx() methods. Fixed store_key_item::copy_inner() to return an error state if an error happened during the call to Item::save_in_field() because it calls Item::val_xxx(). Also added similar checks to related places. --- sql/item.cc | 2 +- sql/sql_select.h | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/sql/item.cc b/sql/item.cc index b35a6ae3d6e..68c10c32b50 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -5141,7 +5141,7 @@ int Item::save_in_field(Field *field, bool no_conversions) field->set_notnull(); error=field->store(nr, unsigned_flag); } - return error; + return error ? error : (field->table->in_use->is_error() ? 2 : 0); } diff --git a/sql/sql_select.h b/sql/sql_select.h index c9cd3ecba42..dd99d358bac 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -709,6 +709,12 @@ public: my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set); int res= item->save_in_field(to_field, 1); + /* + Item::save_in_field() may call Item::val_xxx(). And if this is a subquery + we need to check for errors executing it and react accordingly + */ + if (!res && table->in_use->is_error()) + res= 2; dbug_tmp_restore_column_map(table->write_set, old_map); null_key= to_field->is_null() || item->null_value; return (err != 0 || res > 2 ? STORE_KEY_FATAL : (store_key_result) res); @@ -742,6 +748,12 @@ protected: if (!err) err= res; } + /* + Item::save_in_field() may call Item::val_xxx(). And if this is a subquery + we need to check for errors executing it and react accordingly + */ + if (!err && to_field->table->in_use->is_error()) + err= 2; } null_key= to_field->is_null() || item->null_value; return (err > 2 ? STORE_KEY_FATAL : (store_key_result) err); From 2fdaf377a2ff60147c2545f7fbc3c1b43635b1f4 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 15 Jan 2010 18:03:48 +0100 Subject: [PATCH 108/157] Raise version number after cloning 5.1.43 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 38eb511ac18..e939194697b 100644 --- a/configure.in +++ b/configure.in @@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM # # When changing major version number please also check switch statement # in mysqlbinlog::check_master_version(). -AM_INIT_AUTOMAKE(mysql, 5.1.43) +AM_INIT_AUTOMAKE(mysql, 5.1.44) AM_CONFIG_HEADER([include/config.h:config.h.in]) # Request support for automake silent-rules if available. From 377d710296c3b0c85ea4cdc018d1d8e08bfa022a Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 16 Jan 2010 15:44:24 +0800 Subject: [PATCH 109/157] BUG#47418 RBR fails, failure with mixup of base/temporary/view 'CREATE TABLE IF NOT EXISTS ... SELECT' statement were causing 'CREATE TEMPORARY TABLE ...' to be written to the binary log in row-based mode (a.k.a. RBR), when there was a temporary table with the same name. Because the 'CREATE TABLE ... SELECT' statement was executed as 'INSERT ... SELECT' into the temporary table. Since in RBR mode no other statements related to temporary tables are written into binary log, this sometimes broke replication. This patch changes behavior of 'CREATE TABLE [IF NOT EXISTS] ... SELECT ...'. it ignores existence of temporary table with the same name as table being created and is interpreted as attempt to create/insert into base table. This makes behavior of 'CREATE TABLE [IF NOT EXISTS] ... SELECT' consistent with how ordinary 'CREATE TABLE' and 'CREATE TABLE ... LIKE' behave. --- mysql-test/r/create.result | 7 +-- mysql-test/r/ps_ddl.result | 8 +-- .../rpl/r/rpl_create_if_not_exists.result | 34 ++++++++++++ .../suite/rpl/t/rpl_create_if_not_exists.test | 53 +++++++++++++++++++ mysql-test/t/create.test | 9 ++-- mysql-test/t/ps_ddl.test | 9 ++-- sql/sql_parse.cc | 2 + sql/sql_prepare.cc | 2 + 8 files changed, 106 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index b829ef30fb1..cfdf2565c9c 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -820,16 +820,13 @@ i drop table t1; create temporary table t1 (j int); create table if not exists t1 select 1; -Warnings: -Note 1050 Table 't1' already exists select * from t1; j -1 drop temporary table t1; select * from t1; -ERROR 42S02: Table 'test.t1' doesn't exist +1 +1 drop table t1; -ERROR 42S02: Unknown table 't1' create table t1 (i int); insert into t1 values (1), (2); lock tables t1 read; diff --git a/mysql-test/r/ps_ddl.result b/mysql-test/r/ps_ddl.result index c7e8812320c..375f31ef9c4 100644 --- a/mysql-test/r/ps_ddl.result +++ b/mysql-test/r/ps_ddl.result @@ -1695,23 +1695,23 @@ SUCCESS drop table t2; create temporary table t2 (a int); execute stmt; -ERROR 42S01: Table 't2' already exists call p_verify_reprepare_count(1); SUCCESS execute stmt; ERROR 42S01: Table 't2' already exists -call p_verify_reprepare_count(0); +call p_verify_reprepare_count(1); SUCCESS drop temporary table t2; execute stmt; -call p_verify_reprepare_count(1); +ERROR 42S01: Table 't2' already exists +call p_verify_reprepare_count(0); SUCCESS drop table t2; execute stmt; -call p_verify_reprepare_count(0); +call p_verify_reprepare_count(1); SUCCESS drop table t2; diff --git a/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result b/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result index 12a956a6ce6..fc53aca5136 100644 --- a/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result +++ b/mysql-test/suite/rpl/r/rpl_create_if_not_exists.result @@ -31,3 +31,37 @@ SHOW EVENTS in mysqltest; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation mysqltest e root@localhost SYSTEM ONE TIME # NULL NULL NULL NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci DROP DATABASE IF EXISTS mysqltest; +-------------BUG#47418------------- +USE test; +DROP TABLE IF EXISTS t3; +CREATE TABLE t3(c1 INTEGER); +INSERT INTO t3 VALUES(33); +CREATE TEMPORARY TABLE t1(c1 INTEGER); +CREATE TEMPORARY TABLE t2(c1 INTEGER); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1); +CREATE TABLE IF NOT EXISTS t1(c1 INTEGER) SELECT c1 FROM t3; +CREATE TABLE t2(c1 INTEGER) SELECT c1 FROM t3; +SELECT * FROM t1; +c1 +1 +SELECT * FROM t2; +c1 +1 +SELECT * FROM t1; +c1 +33 +SELECT * FROM t2; +c1 +33 +DROP TEMPORARY TABLE t1; +DROP TEMPORARY TABLE t2; +SELECT * FROM t1; +c1 +33 +SELECT * FROM t2; +c1 +33 +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; diff --git a/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test b/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test index 5faf95a4d84..114f71af873 100644 --- a/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test +++ b/mysql-test/suite/rpl/t/rpl_create_if_not_exists.test @@ -67,4 +67,57 @@ SHOW EVENTS in mysqltest; connection master; DROP DATABASE IF EXISTS mysqltest; + +# +# BUG#47418 RBR fails, failure with mixup of base/temporary/view TABLE DDL +# +# Before the patch for this bug, 'CREATE TABLE IF NOT EXIST ... SELECT' +# statement was binlogged as a TEMPORARY table if the object existed as +# a temporary table. This was caused by that the temporary table was opened +# and the results of the 'SELECT' was inserted into the temporary table if +# a temporary table existed with the same name. +# +# After the patch for this bug, the base table is created and the results of +# the 'SELECT' are inserted into it, even though a temporary table exists with +# the same name, and the statement is still binlogged as a base table. +# + +echo -------------BUG#47418-------------; +connection master; +USE test; +DROP TABLE IF EXISTS t3; +--enable_warnings +CREATE TABLE t3(c1 INTEGER); +INSERT INTO t3 VALUES(33); + +CREATE TEMPORARY TABLE t1(c1 INTEGER); +CREATE TEMPORARY TABLE t2(c1 INTEGER); +INSERT INTO t1 VALUES(1); +INSERT INTO t2 VALUES(1); + +CREATE TABLE IF NOT EXISTS t1(c1 INTEGER) SELECT c1 FROM t3; +CREATE TABLE t2(c1 INTEGER) SELECT c1 FROM t3; + +# In these two statements, t1 and t2 are the temporary table. there is only +# value '1' in them. The records of t2 are not inserted into them. +SELECT * FROM t1; +SELECT * FROM t2; +sync_slave_with_master; + +# In these two statements, t1 and t2 are the base table. The recoreds of t2 +# are inserted into it when CREATE TABLE ... SELECT was executed. +SELECT * FROM t1; +SELECT * FROM t2; + +connection master; +DROP TEMPORARY TABLE t1; +DROP TEMPORARY TABLE t2; +#In these two statements, t1 and t2 are the base table. +SELECT * FROM t1; +SELECT * FROM t2; + +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; + source include/master-slave-end.inc; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 5ffa1b93929..692721b5955 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -721,16 +721,15 @@ drop table t1; # Base vs temporary tables dillema (a.k.a. bug#24508 "Inconsistent # results of CREATE TABLE ... SELECT when temporary table exists"). # In this situation we either have to create non-temporary table and -# insert data in it or insert data in temporary table without creation -# of permanent table. Since currently temporary tables always shadow -# permanent tables we adopt second approach. +# insert data in it or insert data in temporary table without creation of +# permanent table. After patch for Bug#47418, we create the base table and +# instert data into it, even though a temporary table exists with the same +# name. create temporary table t1 (j int); create table if not exists t1 select 1; select * from t1; drop temporary table t1; ---error ER_NO_SUCH_TABLE select * from t1; ---error ER_BAD_TABLE_ERROR drop table t1; diff --git a/mysql-test/t/ps_ddl.test b/mysql-test/t/ps_ddl.test index fee235cd36c..1543c757908 100644 --- a/mysql-test/t/ps_ddl.test +++ b/mysql-test/t/ps_ddl.test @@ -1445,18 +1445,19 @@ call p_verify_reprepare_count(0); drop table t2; # Temporary table with name of table to be created exists create temporary table t2 (a int); +# Temporary table and base table are not in the same name space. +execute stmt; +call p_verify_reprepare_count(1); --error ER_TABLE_EXISTS_ERROR execute stmt; call p_verify_reprepare_count(1); +drop temporary table t2; --error ER_TABLE_EXISTS_ERROR execute stmt; call p_verify_reprepare_count(0); -drop temporary table t2; -execute stmt; -call p_verify_reprepare_count(1); drop table t2; execute stmt; -call p_verify_reprepare_count(0); +call p_verify_reprepare_count(1); drop table t2; # View with name of table to be created exists # Attention: diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index eaea6e55b09..c3070c4a756 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2659,6 +2659,8 @@ mysql_execute_command(THD *thd) { lex->link_first_table_back(create_table, link_to_local); create_table->create= TRUE; + /* Base table and temporary table are not in the same name space. */ + create_table->skip_temporary= 1; } if (!(res= open_and_lock_tables(thd, lex->query_tables))) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index e2a24f7da1e..5979f2ca17e 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1596,6 +1596,8 @@ static bool mysql_test_create_table(Prepared_statement *stmt) { lex->link_first_table_back(create_table, link_to_local); create_table->create= TRUE; + /* Base table and temporary table are not in the same name space. */ + create_table->skip_temporary= true; } if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, 0)) From d1d16f9c3f4310f3ab11fc85b47866d79243a471 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Tue, 19 Jan 2010 00:10:00 +0000 Subject: [PATCH 110/157] Fix for BUG#49481 and BUG#49482 reverted. PB2 run uncovered issue that needs further analysis. --- .../suite/rpl/r/rpl_myisam_null_values.result | 24 --------- .../suite/rpl/t/rpl_myisam_null_values.test | 53 ------------------- sql/log_event.cc | 39 +------------- sql/log_event_old.cc | 39 +------------- 4 files changed, 2 insertions(+), 153 deletions(-) delete mode 100644 mysql-test/suite/rpl/r/rpl_myisam_null_values.result delete mode 100644 mysql-test/suite/rpl/t/rpl_myisam_null_values.test diff --git a/mysql-test/suite/rpl/r/rpl_myisam_null_values.result b/mysql-test/suite/rpl/r/rpl_myisam_null_values.result deleted file mode 100644 index 574528a8d79..00000000000 --- a/mysql-test/suite/rpl/r/rpl_myisam_null_values.result +++ /dev/null @@ -1,24 +0,0 @@ -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; -CREATE TABLE t1 (c1 BIT, c2 INT); -INSERT INTO `t1` VALUES ( 1, 1 ); -UPDATE t1 SET c1=NULL where c2=1; -Comparing tables master:test.t1 and slave:test.t1 -DELETE FROM t1 WHERE c2=1 LIMIT 1; -Comparing tables master:test.t1 and slave:test.t1 -DROP TABLE t1; -CREATE TABLE t1 (c1 CHAR); -INSERT INTO t1 ( c1 ) VALUES ( 'w' ) ; -SELECT * FROM t1; -c1 -w -# should trigger switch to row due to LIMIT -UPDATE t1 SET c1=NULL WHERE c1='w' LIMIT 2; -Comparing tables master:test.t1 and slave:test.t1 -DELETE FROM t1 LIMIT 2; -Comparing tables master:test.t1 and slave:test.t1 -DROP TABLE t1; diff --git a/mysql-test/suite/rpl/t/rpl_myisam_null_values.test b/mysql-test/suite/rpl/t/rpl_myisam_null_values.test deleted file mode 100644 index d9ec95fc510..00000000000 --- a/mysql-test/suite/rpl/t/rpl_myisam_null_values.test +++ /dev/null @@ -1,53 +0,0 @@ -# BUG#49481: RBR: MyISAM and bit fields may cause slave to stop on delete cant find record -# BUG#49482: RBR: Replication may break on deletes when MyISAM tables + char field are used - --- source include/master-slave.inc --- source include/have_binlog_format_mixed_or_row.inc - --- connection master -CREATE TABLE t1 (c1 BIT, c2 INT); -INSERT INTO `t1` VALUES ( 1, 1 ); -UPDATE t1 SET c1=NULL where c2=1; --- sync_slave_with_master - --- let $diff_table_1=master:test.t1 --- let $diff_table_2=slave:test.t1 --- source include/diff_tables.inc - --- connection master -DELETE FROM t1 WHERE c2=1 LIMIT 1; --- sync_slave_with_master - --- let $diff_table_1=master:test.t1 --- let $diff_table_2=slave:test.t1 --- source include/diff_tables.inc - --- connection master -DROP TABLE t1; --- sync_slave_with_master - --- connection master - -CREATE TABLE t1 (c1 CHAR); - -INSERT INTO t1 ( c1 ) VALUES ( 'w' ) ; -SELECT * FROM t1; --- echo # should trigger switch to row due to LIMIT -UPDATE t1 SET c1=NULL WHERE c1='w' LIMIT 2; --- sync_slave_with_master - --- let $diff_table_1=master:test.t1 --- let $diff_table_2=slave:test.t1 --- source include/diff_tables.inc - --- connection master -DELETE FROM t1 LIMIT 2; --- sync_slave_with_master - --- let $diff_table_1=master:test.t1 --- let $diff_table_2=slave:test.t1 --- source include/diff_tables.inc - --- connection master -DROP TABLE t1; --- sync_slave_with_master diff --git a/sql/log_event.cc b/sql/log_event.cc index 61f5e93e29e..6b21087b6aa 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -8724,24 +8724,6 @@ static bool record_compare(TABLE *table) } } - /** - Check if we are using MyISAM. - - If this is a myisam table, then we cannot do a memcmp - right away because some NULL fields can still contain - an old value in the row - they are not shown to the user - because the null bit is set, however, the contents are - not cleared. As such, plain memory comparison cannot be - assured to work. See: BUG#49482 and BUG#49481. - - On top of this, we do not store field contents for null - fields in the binlog, so this is extra important when - comparing records fetched from binlog and from storage - engine. - */ - if (table->file->ht->db_type == DB_TYPE_MYISAM) - goto record_compare_field_by_field; - if (table->s->blob_fields + table->s->varchar_fields == 0) { result= cmp_record(table,record[1]); @@ -8757,33 +8739,14 @@ static bool record_compare(TABLE *table) goto record_compare_exit; } -record_compare_field_by_field: - /* Compare updated fields */ for (Field **ptr=table->field ; *ptr ; ptr++) { - Field *f= *ptr; - - /* if just one of the fields is null then there is no match */ - if ((f->is_null_in_record(table->record[0])) == - !(f->is_null_in_record(table->record[1]))) + if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length)) { result= TRUE; goto record_compare_exit; } - - /* if both fields are not null then we can compare */ - if (!(f->is_null_in_record(table->record[0])) && - !(f->is_null_in_record(table->record[1]))) - { - if (f->cmp_binary_offset(table->s->rec_buff_length)) - { - result= TRUE; - goto record_compare_exit; - } - } - - /* if both fields are null then there is a match. compare next field */ } record_compare_exit: diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 72a6e159535..357bc78b1cd 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -351,24 +351,6 @@ static bool record_compare(TABLE *table) } } - /** - Check if we are using MyISAM. - - If this is a myisam table, then we cannot do a memcmp - right away because some NULL fields can still contain - an old value in the row - they are not shown to the user - because the null bit is set, however, the contents are - not cleared. As such, plain memory comparison cannot be - assured to work. See: BUG#49482 and BUG#49481. - - On top of this, we do not store field contents for null - fields in the binlog, so this is extra important when - comparing records fetched from binlog and from storage - engine. - */ - if (table->file->ht->db_type == DB_TYPE_MYISAM) - goto record_compare_field_by_field; - if (table->s->blob_fields + table->s->varchar_fields == 0) { result= cmp_record(table,record[1]); @@ -384,33 +366,14 @@ static bool record_compare(TABLE *table) goto record_compare_exit; } -record_compare_field_by_field: - /* Compare updated fields */ for (Field **ptr=table->field ; *ptr ; ptr++) { - Field *f= *ptr; - - /* if just one of the fields is null then there is no match */ - if ((f->is_null_in_record(table->record[0])) == - !(f->is_null_in_record(table->record[1]))) + if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length)) { result= TRUE; goto record_compare_exit; } - - /* if both fields are not null then we can compare */ - if (!(f->is_null_in_record(table->record[0])) && - !(f->is_null_in_record(table->record[1]))) - { - if (f->cmp_binary_offset(table->s->rec_buff_length)) - { - result= TRUE; - goto record_compare_exit; - } - } - - /* if both fields are null then there is a match. compare next field */ } record_compare_exit: From 4839c42619304989a44dc8f57a800f311ae93bb4 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Tue, 19 Jan 2010 17:02:51 +0100 Subject: [PATCH 111/157] post-push patch for bug#47343. Missing ha_rnd_end in copy_partitions, found due to a DBUG_ASSERT in mysql-pe sql/ha_partition.cc: Post-push patch for bug#47343 Must call ha_rnd_end since ha_rnd_init has been called. --- sql/ha_partition.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 555a0b97ddd..7b9ecd7d902 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1705,6 +1705,7 @@ int ha_partition::copy_partitions(ulonglong * const copied, } DBUG_RETURN(FALSE); error: + m_reorged_file[reorg_part]->ha_rnd_end(); DBUG_RETURN(result); } From 985c06d0a9bd230cbab2e3cbfb7fbf744ea7ee3e Mon Sep 17 00:00:00 2001 From: Alfranio Correia Date: Wed, 20 Jan 2010 19:08:16 +0000 Subject: [PATCH 112/157] BUG#46364 MyISAM transbuffer problems (NTM problem) It is well-known that due to concurrency issues, a slave can become inconsistent when a transaction contains updates to both transaction and non-transactional tables in statement and mixed modes. In a nutshell, the current code-base tries to preserve causality among the statements by writing non-transactional statements to the txn-cache which is flushed upon commit. However, modifications done to non-transactional tables on behalf of a transaction become immediately visible to other connections but may not immediately get into the binary log and therefore consistency may be broken. In general, it is impossible to automatically detect causality/dependency among statements by just analyzing the statements sent to the server. This happen because dependency may be hidden in the application code and it is necessary to know a priori all the statements processed in the context of a transaction such as in a procedure. Moreover, even for the few cases that we could automatically address in the server, the computation effort required could make the approach infeasible. So, in this patch we introduce the option - "--binlog-direct-non-transactional-updates" that can be used to bypass the current behavior in order to write directly to binary log statements that change non-transactional tables. mysql-test/extra/rpl_tests/rpl_mixing_engines.inc: Backported this from Celosia to improve the test cases related to the NTM issue. sql/log.cc: Checks the --binlog-direct-non-transactional-updates before choosing to either use the trxn-cache or not. sql/mysqld.cc: Introduces the option --binlog-direct-non-transactional-updates. sql/set_var.cc: Introduces the option --binlog-direct-non-transactional-updates. sql/sql_class.h: Introduces the option --binlog-direct-non-transactional-updates. --- .../extra/rpl_tests/rpl_mixing_engines.inc | 554 +++++++ .../suite/rpl/r/rpl_stm_binlog_direct.result | 1360 +++++++++++++++++ .../rpl/t/rpl_stm_binlog_direct-master.opt | 1 + .../suite/rpl/t/rpl_stm_binlog_direct.test | 230 +++ sql/log.cc | 23 +- sql/mysqld.cc | 7 +- sql/set_var.cc | 2 + sql/sql_class.h | 1 + 8 files changed, 2170 insertions(+), 8 deletions(-) create mode 100644 mysql-test/extra/rpl_tests/rpl_mixing_engines.inc create mode 100644 mysql-test/suite/rpl/r/rpl_stm_binlog_direct.result create mode 100644 mysql-test/suite/rpl/t/rpl_stm_binlog_direct-master.opt create mode 100644 mysql-test/suite/rpl/t/rpl_stm_binlog_direct.test diff --git a/mysql-test/extra/rpl_tests/rpl_mixing_engines.inc b/mysql-test/extra/rpl_tests/rpl_mixing_engines.inc new file mode 100644 index 00000000000..6dde3e079a1 --- /dev/null +++ b/mysql-test/extra/rpl_tests/rpl_mixing_engines.inc @@ -0,0 +1,554 @@ +################################################################################ +# This is an auxiliary file used by rpl_mixing_engines.test, and that it +# executes SQL statements according to a format string, as specified in +# rpl_mixing_engines.test. In addition, it accepts the special format +# strings 'configure' and 'clean', used before and after everything else. +################################################################################ + +if (`SELECT HEX(@commands) = HEX('configure')`) +{ + connection master; + + SET SQL_LOG_BIN=0; + eval CREATE TABLE nt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE nt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE nt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE nt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE nt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE nt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE tt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + eval CREATE TABLE tt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + eval CREATE TABLE tt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + eval CREATE TABLE tt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + eval CREATE TABLE tt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + eval CREATE TABLE tt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + eval SET SQL_LOG_BIN=1; + + connection slave; + + SET SQL_LOG_BIN=0; + eval CREATE TABLE nt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE nt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE nt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE nt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE nt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE nt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; + eval CREATE TABLE tt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + eval CREATE TABLE tt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + eval CREATE TABLE tt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + eval CREATE TABLE tt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + eval CREATE TABLE tt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + eval CREATE TABLE tt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = $engine_type; + SET SQL_LOG_BIN=1; + + connection master; + + INSERT INTO nt_1(trans_id, stmt_id) VALUES(1,1); + INSERT INTO nt_2(trans_id, stmt_id) VALUES(1,1); + INSERT INTO nt_3(trans_id, stmt_id) VALUES(1,1); + INSERT INTO nt_4(trans_id, stmt_id) VALUES(1,1); + INSERT INTO nt_5(trans_id, stmt_id) VALUES(1,1); + INSERT INTO nt_6(trans_id, stmt_id) VALUES(1,1); + + INSERT INTO tt_1(trans_id, stmt_id) VALUES(1,1); + INSERT INTO tt_2(trans_id, stmt_id) VALUES(1,1); + INSERT INTO tt_3(trans_id, stmt_id) VALUES(1,1); + INSERT INTO tt_4(trans_id, stmt_id) VALUES(1,1); + INSERT INTO tt_5(trans_id, stmt_id) VALUES(1,1); + INSERT INTO tt_6(trans_id, stmt_id) VALUES(1,1); + + DELIMITER |; + + CREATE PROCEDURE pc_i_tt_5_suc (IN p_trans_id INTEGER, IN p_stmt_id INTEGER) + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM tt_5 WHERE trans_id= p_trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id; + INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id); + INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1); + END| + + CREATE PROCEDURE pc_i_nt_5_suc (IN p_trans_id INTEGER, IN p_stmt_id INTEGER) + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM nt_5 WHERE trans_id= p_trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id; + INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id); + INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1); + END| + + CREATE FUNCTION fc_i_tt_5_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64) + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM tt_5 WHERE trans_id= p_trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id; + INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id); + INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1); + RETURN "fc_i_tt_5_suc"; + END| + + CREATE FUNCTION fc_i_nt_5_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64) + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM nt_5 WHERE trans_id= p_trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id; + INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id); + INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1); + RETURN "fc_i_nt_5_suc"; + END| + + CREATE TRIGGER tr_i_tt_3_to_nt_3 AFTER INSERT ON tt_3 FOR EACH ROW + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM nt_3 WHERE trans_id= NEW.trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id; + INSERT INTO nt_3(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id); + INSERT INTO nt_3(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1); + END| + + CREATE TRIGGER tr_i_nt_4_to_tt_4 AFTER INSERT ON nt_4 FOR EACH ROW + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM tt_4 WHERE trans_id= NEW.trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id; + INSERT INTO tt_4(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id); + INSERT INTO tt_4(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1); + END| + + CREATE TRIGGER tr_i_tt_5_to_tt_6 AFTER INSERT ON tt_5 FOR EACH ROW + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM tt_6 WHERE trans_id= NEW.trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id, 1), 1) INTO in_stmt_id; + INSERT INTO tt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id); + INSERT INTO tt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1); + END| + + CREATE TRIGGER tr_i_nt_5_to_nt_6 AFTER INSERT ON nt_5 FOR EACH ROW + BEGIN + DECLARE in_stmt_id INTEGER; + SELECT max(stmt_id) INTO in_stmt_id FROM nt_6 WHERE trans_id= NEW.trans_id; + SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id; + INSERT INTO nt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id); + INSERT INTO nt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1); + END| + + DELIMITER ;| + + let $pos_trans_command= query_get_value("SHOW MASTER STATUS", Position, 1); + + let $trans_id= 7; + let $tb_id= 1; + let $stmt_id= 1; + let $commands= ''; + + SET @commands= ''; +} + +if (`SELECT HEX(@commands) = HEX('clean')`) +{ + connection master; + + DROP TABLE tt_1; + DROP TABLE tt_2; + DROP TABLE tt_3; + DROP TABLE tt_4; + DROP TABLE tt_5; + DROP TABLE tt_6; + + DROP TABLE nt_1; + DROP TABLE nt_2; + DROP TABLE nt_3; + DROP TABLE nt_4; + DROP TABLE nt_5; + DROP TABLE nt_6; + + DROP PROCEDURE pc_i_tt_5_suc; + DROP PROCEDURE pc_i_nt_5_suc; + DROP FUNCTION fc_i_tt_5_suc; + DROP FUNCTION fc_i_nt_5_suc; + + sync_slave_with_master; + + SET @commands= ''; +} + +while (`SELECT HEX(@commands) != HEX('')`) +{ + --disable_query_log + SET @command= SUBSTRING_INDEX(@commands, ' ', 1); + let $command= `SELECT @command`; + --eval SET @check_commands= '$commands' + if (`SELECT HEX(@check_commands) = HEX('''')`) + { + let $commands= `SELECT @commands`; + } + --echo -b-b-b-b-b-b-b-b-b-b-b- >> $command << -b-b-b-b-b-b-b-b-b-b-b- + let $pos_command= query_get_value("SHOW MASTER STATUS", Position, 1); + --enable_query_log + if (`SELECT HEX(@command) = HEX('B')`) + { + eval BEGIN; + } + if (`SELECT HEX(@command) = HEX('T')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO tt_1(trans_id, stmt_id) VALUES ($trans_id, $stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('T-trig')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO tt_5(trans_id, stmt_id) VALUES ($trans_id, $stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('T-func')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval SELECT fc_i_tt_5_suc ($trans_id, $stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('T-proc')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval CALL pc_i_tt_5_suc ($trans_id, $stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('eT')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from tt_1`; + let $old_stmt_id= `SELECT max(stmt_id) from tt_1 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO tt_1(trans_id, stmt_id) VALUES ($old_trans_id, $old_stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('Te')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from tt_1`; + let $old_stmt_id= `SELECT max(stmt_id) from tt_1 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO tt_1(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('Te-trig')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from tt_5`; + let $old_stmt_id= `SELECT max(stmt_id) from tt_5 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO tt_5(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('Te-func')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from tt_1`; + let $old_stmt_id= `SELECT max(stmt_id) from tt_1 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO tt_1(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, ''), ($old_trans_id, $old_stmt_id, fc_i_tt_5_suc ($trans_id, $stmt_id)); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('N')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO nt_1(trans_id, stmt_id) VALUES ($trans_id, $stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('N-trig')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO nt_5(trans_id, stmt_id) VALUES ($trans_id, $stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('N-func')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval SELECT fc_i_nt_5_suc ($trans_id, $stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('N-proc')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval CALL pc_i_nt_5_suc ($trans_id, $stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('eN')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from nt_1`; + let $old_stmt_id= `SELECT max(stmt_id) from nt_1 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO nt_1(trans_id, stmt_id) VALUES ($old_trans_id, $old_stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('Ne')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from nt_1`; + let $old_stmt_id= `SELECT max(stmt_id) from nt_1 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO nt_1(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('Ne-trig')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from nt_5`; + let $old_stmt_id= `SELECT max(stmt_id) from nt_5 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO nt_5(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('Ne-func')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from nt_1`; + let $old_stmt_id= `SELECT max(stmt_id) from nt_1 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO nt_1(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, ''), ($old_trans_id, $old_stmt_id, fc_i_nt_5_suc ($trans_id, $stmt_id)); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('tN')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO nt_1(trans_id, stmt_id, info) SELECT $trans_id, $stmt_id, COUNT(*) FROM tt_1; + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('tNe')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from nt_1`; + let $old_stmt_id= `SELECT max(stmt_id) from nt_1 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO nt_1(trans_id, stmt_id, info) SELECT $trans_id, $stmt_id, COUNT(*) FROM tt_1 UNION SELECT $old_trans_id, $old_stmt_id, COUNT(*) FROM tt_1; + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('nT')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO tt_1(trans_id, stmt_id, info) SELECT $trans_id, $stmt_id, COUNT(*) FROM nt_1; + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('nTe')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from tt_1`; + let $old_stmt_id= `SELECT max(stmt_id) from tt_1 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO tt_1(trans_id, stmt_id, info) SELECT $trans_id, $stmt_id, COUNT(*) FROM nt_1 UNION SELECT $old_trans_id, $old_stmt_id, COUNT(*) FROM nt_1; + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('NT')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval UPDATE nt_3, tt_3 SET nt_3.info= "new text $trans_id --> $stmt_id", tt_3.info= "new text $trans_id --> $stmt_id" where nt_3.trans_id = tt_3.trans_id and tt_3.trans_id = 1; + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('NT-trig')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO nt_4(trans_id, stmt_id) VALUES ($trans_id, $stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('NT-func')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO nt_5(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, fc_i_tt_5_suc($trans_id, $stmt_id)); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('NeT-trig')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from nt_4`; + let $old_stmt_id= `SELECT max(stmt_id) from nt_4 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO nt_4(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('NeT-func')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from nt_5`; + let $old_stmt_id= `SELECT max(stmt_id) from nt_5 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO nt_5(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, ''), ($old_trans_id, $old_stmt_id, fc_i_tt_5_suc ($trans_id, $stmt_id)); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('TN')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval UPDATE tt_4, nt_4 SET tt_4.info= "new text $trans_id --> $stmt_id", nt_4.info= "new text $trans_id --> $stmt_id" where nt_4.trans_id = tt_4.trans_id and tt_4.trans_id = 1; + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('TN-trig')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO tt_3(trans_id, stmt_id) VALUES ($trans_id, $stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('TN-func')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + eval INSERT INTO tt_5(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, fc_i_nt_5_suc($trans_id, $stmt_id)); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('TeN-trig')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from tt_3`; + let $old_stmt_id= `SELECT max(stmt_id) from tt_3 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO tt_3(trans_id, stmt_id) VALUES ($trans_id, $stmt_id), ($old_trans_id, $old_stmt_id); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('TeN-func')`) + { + #--echo DEBUG-- (trans_id, stmt_id) --> ($trans_id, $stmt_id) + let $old_trans_id= `SELECT max(trans_id) from tt_5`; + let $old_stmt_id= `SELECT max(stmt_id) from tt_5 where trans_id= $old_trans_id`; + --error ER_DUP_ENTRY, ER_DUP_KEY + eval INSERT INTO tt_5(trans_id, stmt_id, info) VALUES ($trans_id, $stmt_id, ''), ($old_trans_id, $old_stmt_id, fc_i_nt_5_suc ($trans_id, $stmt_id)); + inc $stmt_id; + } + if (`SELECT HEX(@command) = HEX('CS-T->T')`) + { + --eval CREATE TABLE tt_xx_$tb_id (PRIMARY KEY(trans_id, stmt_id)) engine=$engine_type SELECT * FROM tt_1; + } + if (`SELECT HEX(@command) = HEX('CS-N->N')`) + { + --eval CREATE TABLE nt_xx_$tb_id (PRIMARY KEY(trans_id, stmt_id)) engine=MyIsam SELECT * FROM nt_1; + } + if (`SELECT HEX(@command) = HEX('CS-T->N')`) + { + --eval CREATE TABLE tt_xx_$tb_id (PRIMARY KEY(trans_id, stmt_id)) engine=$engine_type SELECT * FROM nt_1; + } + if (`SELECT HEX(@command) = HEX('CS-N->T')`) + { + --eval CREATE TABLE nt_xx_$tb_id (PRIMARY KEY(trans_id, stmt_id)) engine=MyIsam SELECT * FROM tt_1; + } + if (`SELECT HEX(@command) = HEX('CSe-T->T')`) + { + --error ER_DUP_ENTRY, ER_DUP_KEY + --eval CREATE TABLE tt_xx_$tb_id (PRIMARY KEY (stmt_id)) engine=$engine_type SELECT stmt_id FROM tt_1; + } + if (`SELECT HEX(@command) = HEX('CSe-N->N')`) + { + --error ER_DUP_ENTRY, ER_DUP_KEY + --eval CREATE TABLE nt_xx_$tb_id (PRIMARY KEY (stmt_id)) engine=MyIsam SELECT stmt_id FROM nt_1; + } + if (`SELECT HEX(@command) = HEX('CSe-T->N')`) + { + --error ER_DUP_ENTRY, ER_DUP_KEY + --eval CREATE TABLE tt_xx_$tb_id (PRIMARY KEY (stmt_id)) engine=$engine_type SELECT stmt_id FROM nt_1; + } + if (`SELECT HEX(@command) = HEX('CSe-N->T')`) + { + --error ER_DUP_ENTRY, ER_DUP_KEY + --eval CREATE TABLE nt_xx_$tb_id (PRIMARY KEY (stmt_id)) engine=MyIsam SELECT stmt_id FROM tt_1; + } + if (`SELECT HEX(@command) = HEX('CT')`) + { + --eval CREATE TEMPORARY TABLE tt_xx_$tb_id (a int) engine=$engine_type; + } + if (`SELECT HEX(@command) = HEX('IS-T<-N')`) + { + --eval INSERT INTO tt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, stmt_id, USER() FROM nt_1; + } + if (`SELECT HEX(@command) = HEX('ISe-T<-N')`) + { + --error ER_DUP_ENTRY, ER_DUP_KEY + --eval INSERT INTO tt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, trans_id, USER() FROM nt_1; + } + if (`SELECT HEX(@command) = HEX('IS-N<-T')`) + { + --eval INSERT INTO nt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, stmt_id, USER() FROM tt_1; + } + if (`SELECT HEX(@command) = HEX('ISe-N<-T')`) + { + --error ER_DUP_ENTRY, ER_DUP_KEY + --eval INSERT INTO nt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, trans_id, USER() FROM tt_1; + } + if (`SELECT HEX(@command) = HEX('IS-T<-T')`) + { + --eval INSERT INTO tt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, stmt_id, USER() FROM tt_1; + } + if (`SELECT HEX(@command) = HEX('ISe-T<-T')`) + { + --error ER_DUP_ENTRY, ER_DUP_KEY + --eval INSERT INTO tt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, trans_id, USER() FROM tt_1; + } + if (`SELECT HEX(@command) = HEX('IS-N<-N')`) + { + --eval INSERT INTO nt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, stmt_id, USER() FROM nt_1; + } + if (`SELECT HEX(@command) = HEX('ISe-N<-N')`) + { + --error ER_DUP_ENTRY, ER_DUP_KEY + --eval INSERT INTO nt_xx_$tb_id(trans_id, stmt_id, info) SELECT trans_id, trans_id, USER() FROM nt_1; + } + if (`SELECT HEX(@command) = HEX('trunc-CS-T')`) + { + eval TRUNCATE TABLE tt_xx_$tb_id; + } + if (`SELECT HEX(@command) = HEX('trunc-CS-N')`) + { + eval TRUNCATE TABLE nt_xx_$tb_id; + } + if (`SELECT HEX(@command) = HEX('trunc-CT')`) + { + eval TRUNCATE TABLE tt_xx_$tb_id; + } + if (`SELECT HEX(@command) = HEX('drop-CS')`) + { + --disable_warnings + eval DROP TABLE IF EXISTS tt_xx_$tb_id, nt_xx_$tb_id; + inc $tb_id; + --enable_warnings + } + if (`SELECT HEX(@command) = HEX('drop-CT')`) + { + --disable_warnings + eval DROP TEMPORARY TABLE IF EXISTS tt_xx_$tb_id; + inc $tb_id; + --enable_warnings + } + if (`SELECT HEX(@command) = HEX('C')`) + { + --error 0, ER_GET_ERRMSG + eval COMMIT; + } + if (`SELECT HEX(@command) = HEX('R')`) + { + --error 0, ER_GET_ERRMSG + eval ROLLBACK; + } + if (`SELECT HEX(@command) = HEX('S1')`) + { + eval SAVEPOINT s1; + } + if (`SELECT HEX(@command) = HEX('R1')`) + { + eval ROLLBACK TO s1; + } + --disable_query_log + SET @commands= LTRIM(SUBSTRING(@commands, LENGTH(@command) + 1)); + inc $stmt_id; + + let $binlog_start= $pos_command; + --source include/show_binlog_events.inc + --echo -e-e-e-e-e-e-e-e-e-e-e- >> $command << -e-e-e-e-e-e-e-e-e-e-e- + if (`SELECT HEX(@commands) = HEX('')`) + { + let $binlog_start= $pos_trans_command; + --echo -b-b-b-b-b-b-b-b-b-b-b- >> $commands << -b-b-b-b-b-b-b-b-b-b-b- + --source include/show_binlog_events.inc + --echo -e-e-e-e-e-e-e-e-e-e-e- >> $commands << -e-e-e-e-e-e-e-e-e-e-e- + --echo + let $pos_trans_command= query_get_value("SHOW MASTER STATUS", Position, 1); + let $stmt_id= 1; + inc $trans_id; + let $commands= ''; + } +} diff --git a/mysql-test/suite/rpl/r/rpl_stm_binlog_direct.result b/mysql-test/suite/rpl/r/rpl_stm_binlog_direct.result new file mode 100644 index 00000000000..818e383e2f1 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_stm_binlog_direct.result @@ -0,0 +1,1360 @@ +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; +set @@session.binlog_direct_non_transactional_updates= TRUE; +######################################################################### +# CONFIGURATION +######################################################################### +SET @commands= 'configure'; +SET SQL_LOG_BIN=0; +CREATE TABLE nt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; +CREATE TABLE nt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; +CREATE TABLE nt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; +CREATE TABLE nt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; +CREATE TABLE nt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; +CREATE TABLE nt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; +CREATE TABLE tt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb; +CREATE TABLE tt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb; +CREATE TABLE tt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb; +CREATE TABLE tt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb; +CREATE TABLE tt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb; +CREATE TABLE tt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb; +SET SQL_LOG_BIN=1; +SET SQL_LOG_BIN=0; +CREATE TABLE nt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; +CREATE TABLE nt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; +CREATE TABLE nt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; +CREATE TABLE nt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; +CREATE TABLE nt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; +CREATE TABLE nt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = MyISAM; +CREATE TABLE tt_1 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb; +CREATE TABLE tt_2 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb; +CREATE TABLE tt_3 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb; +CREATE TABLE tt_4 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb; +CREATE TABLE tt_5 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb; +CREATE TABLE tt_6 (trans_id INT, stmt_id INT, info VARCHAR(64), PRIMARY KEY(trans_id, stmt_id)) ENGINE = Innodb; +SET SQL_LOG_BIN=1; +INSERT INTO nt_1(trans_id, stmt_id) VALUES(1,1); +INSERT INTO nt_2(trans_id, stmt_id) VALUES(1,1); +INSERT INTO nt_3(trans_id, stmt_id) VALUES(1,1); +INSERT INTO nt_4(trans_id, stmt_id) VALUES(1,1); +INSERT INTO nt_5(trans_id, stmt_id) VALUES(1,1); +INSERT INTO nt_6(trans_id, stmt_id) VALUES(1,1); +INSERT INTO tt_1(trans_id, stmt_id) VALUES(1,1); +INSERT INTO tt_2(trans_id, stmt_id) VALUES(1,1); +INSERT INTO tt_3(trans_id, stmt_id) VALUES(1,1); +INSERT INTO tt_4(trans_id, stmt_id) VALUES(1,1); +INSERT INTO tt_5(trans_id, stmt_id) VALUES(1,1); +INSERT INTO tt_6(trans_id, stmt_id) VALUES(1,1); +CREATE PROCEDURE pc_i_tt_5_suc (IN p_trans_id INTEGER, IN p_stmt_id INTEGER) +BEGIN +DECLARE in_stmt_id INTEGER; +SELECT max(stmt_id) INTO in_stmt_id FROM tt_5 WHERE trans_id= p_trans_id; +SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id; +INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id); +INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1); +END| +CREATE PROCEDURE pc_i_nt_5_suc (IN p_trans_id INTEGER, IN p_stmt_id INTEGER) +BEGIN +DECLARE in_stmt_id INTEGER; +SELECT max(stmt_id) INTO in_stmt_id FROM nt_5 WHERE trans_id= p_trans_id; +SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id; +INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id); +INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1); +END| +CREATE FUNCTION fc_i_tt_5_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64) +BEGIN +DECLARE in_stmt_id INTEGER; +SELECT max(stmt_id) INTO in_stmt_id FROM tt_5 WHERE trans_id= p_trans_id; +SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id; +INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id); +INSERT INTO tt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1); +RETURN "fc_i_tt_5_suc"; +END| +CREATE FUNCTION fc_i_nt_5_suc (p_trans_id INTEGER, p_stmt_id INTEGER) RETURNS VARCHAR(64) +BEGIN +DECLARE in_stmt_id INTEGER; +SELECT max(stmt_id) INTO in_stmt_id FROM nt_5 WHERE trans_id= p_trans_id; +SELECT COALESCE(greatest(in_stmt_id + 1, p_stmt_id), 1) INTO in_stmt_id; +INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id); +INSERT INTO nt_5(trans_id, stmt_id) VALUES (p_trans_id, in_stmt_id + 1); +RETURN "fc_i_nt_5_suc"; +END| +CREATE TRIGGER tr_i_tt_3_to_nt_3 AFTER INSERT ON tt_3 FOR EACH ROW +BEGIN +DECLARE in_stmt_id INTEGER; +SELECT max(stmt_id) INTO in_stmt_id FROM nt_3 WHERE trans_id= NEW.trans_id; +SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id; +INSERT INTO nt_3(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id); +INSERT INTO nt_3(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1); +END| +CREATE TRIGGER tr_i_nt_4_to_tt_4 AFTER INSERT ON nt_4 FOR EACH ROW +BEGIN +DECLARE in_stmt_id INTEGER; +SELECT max(stmt_id) INTO in_stmt_id FROM tt_4 WHERE trans_id= NEW.trans_id; +SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id; +INSERT INTO tt_4(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id); +INSERT INTO tt_4(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1); +END| +CREATE TRIGGER tr_i_tt_5_to_tt_6 AFTER INSERT ON tt_5 FOR EACH ROW +BEGIN +DECLARE in_stmt_id INTEGER; +SELECT max(stmt_id) INTO in_stmt_id FROM tt_6 WHERE trans_id= NEW.trans_id; +SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id, 1), 1) INTO in_stmt_id; +INSERT INTO tt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id); +INSERT INTO tt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1); +END| +CREATE TRIGGER tr_i_nt_5_to_nt_6 AFTER INSERT ON nt_5 FOR EACH ROW +BEGIN +DECLARE in_stmt_id INTEGER; +SELECT max(stmt_id) INTO in_stmt_id FROM nt_6 WHERE trans_id= NEW.trans_id; +SELECT COALESCE(greatest(in_stmt_id + 1, NEW.stmt_id), 1) INTO in_stmt_id; +INSERT INTO nt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id); +INSERT INTO nt_6(trans_id, stmt_id) VALUES (NEW.trans_id, in_stmt_id + 1); +END| +SET @commands= ''; +######################################################################### +# 1 - BINLOG ORDER +######################################################################### + + + + +# +#3) Generates in the binlog what follows: +# --> STMT "N B T C" entries, format S. +# +SET @commands= 'B T N C'; +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(trans_id, stmt_id) VALUES (7, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_1(trans_id, stmt_id) VALUES (7, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (7, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (7, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T N C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (7, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (7, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T N C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(trans_id, stmt_id) VALUES (8, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_5(trans_id, stmt_id) VALUES (8, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (8, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (8, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T N-trig C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (8, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (8, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T N-trig C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(trans_id, stmt_id) VALUES (9, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b- +SELECT fc_i_nt_5_suc (9, 4); +fc_i_nt_5_suc (9, 4) +fc_i_nt_5_suc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(9,4) +-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (9, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T N-func C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(9,4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (9, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T N-func C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(trans_id, stmt_id) VALUES (10, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b- +CALL pc_i_nt_5_suc (10, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',10), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',10), NAME_CONST('in_stmt_id',1) + 1) +-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (10, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T N-proc C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',10), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',10), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (10, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T N-proc C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_5(trans_id, stmt_id) VALUES (11, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_1(trans_id, stmt_id) VALUES (11, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (11, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (11, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-trig N C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (11, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (11, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T-trig N C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_5(trans_id, stmt_id) VALUES (12, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_5(trans_id, stmt_id) VALUES (12, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (12, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (12, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-trig N-trig C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (12, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (12, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T-trig N-trig C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_5(trans_id, stmt_id) VALUES (13, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b- +SELECT fc_i_nt_5_suc (13, 4); +fc_i_nt_5_suc (13, 4) +fc_i_nt_5_suc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(13,4) +-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (13, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-trig N-func C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(13,4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (13, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T-trig N-func C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_5(trans_id, stmt_id) VALUES (14, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b- +CALL pc_i_nt_5_suc (14, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',14), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',14), NAME_CONST('in_stmt_id',1) + 1) +-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (14, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-trig N-proc C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',14), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',14), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (14, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T-trig N-proc C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b- +SELECT fc_i_tt_5_suc (15, 2); +fc_i_tt_5_suc (15, 2) +fc_i_tt_5_suc +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_1(trans_id, stmt_id) VALUES (15, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (15, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(15,2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-func N C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (15, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(15,2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T-func N C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b- +SELECT fc_i_tt_5_suc (16, 2); +fc_i_tt_5_suc (16, 2) +fc_i_tt_5_suc +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_5(trans_id, stmt_id) VALUES (16, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (16, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(16,2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-func N-trig C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (16, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(16,2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T-func N-trig C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b- +SELECT fc_i_tt_5_suc (17, 2); +fc_i_tt_5_suc (17, 2) +fc_i_tt_5_suc +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b- +SELECT fc_i_nt_5_suc (17, 4); +fc_i_nt_5_suc (17, 4) +fc_i_nt_5_suc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(17,4) +-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(17,2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-func N-func C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(17,4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(17,2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T-func N-func C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b- +SELECT fc_i_tt_5_suc (18, 2); +fc_i_tt_5_suc (18, 2) +fc_i_tt_5_suc +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b- +CALL pc_i_nt_5_suc (18, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',18), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',18), NAME_CONST('in_stmt_id',1) + 1) +-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(18,2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-func N-proc C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',18), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',18), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(18,2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T-func N-proc C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b- +CALL pc_i_tt_5_suc (19, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_1(trans_id, stmt_id) VALUES (19, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (19, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',19), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',19), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-proc N C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (19, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',19), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',19), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T-proc N C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b- +CALL pc_i_tt_5_suc (20, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_5(trans_id, stmt_id) VALUES (20, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (20, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',20), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',20), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-proc N-trig C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (20, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',20), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',20), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T-proc N-trig C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b- +CALL pc_i_tt_5_suc (21, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b- +SELECT fc_i_nt_5_suc (21, 4); +fc_i_nt_5_suc (21, 4) +fc_i_nt_5_suc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(21,4) +-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',21), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',21), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-proc N-func C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(21,4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',21), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',21), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T-proc N-func C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b- +CALL pc_i_tt_5_suc (22, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b- +CALL pc_i_nt_5_suc (22, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',22), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',22), NAME_CONST('in_stmt_id',1) + 1) +-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',22), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',22), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-proc N-proc C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',22), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',22), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',22), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',22), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T-proc N-proc C << -e-e-e-e-e-e-e-e-e-e-e- + + + + + +# +#3.e) Generates in the binlog what follows if T-* fails: +# --> STMT "N" entry, format S. +# Otherwise, what follows if N-* fails and a N-Table is changed: +# --> STMT "N B T C" entries, format S. +# +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> eT << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(trans_id, stmt_id) VALUES (10, 2); +Got one of the listed errors +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> eT << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_1(trans_id, stmt_id) VALUES (23, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (23, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B eT N C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (23, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> B eT N C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> Te << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(trans_id, stmt_id) VALUES (24, 2), (10, 2); +Got one of the listed errors +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> Te << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_1(trans_id, stmt_id) VALUES (24, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (24, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B Te N C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (24, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> B Te N C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(trans_id, stmt_id) VALUES (25, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> eN << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_1(trans_id, stmt_id) VALUES (24, 4); +Got one of the listed errors +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> eN << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (25, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T eN C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (25, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T eN C << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(trans_id, stmt_id) VALUES (26, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> Ne << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_1(trans_id, stmt_id) VALUES (26, 4), (24, 4); +Got one of the listed errors +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (26, 4), (24, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> Ne << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> C << -b-b-b-b-b-b-b-b-b-b-b- +COMMIT; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (26, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> C << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T Ne C << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (26, 4), (24, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (26, 2) +master-bin.000001 # Xid # # COMMIT /* XID */ +-e-e-e-e-e-e-e-e-e-e-e- >> B T Ne C << -e-e-e-e-e-e-e-e-e-e-e- + + + + + +# +#4) Generates in the binlog what follows: +# --> STMT "N B T R" entries, format S. +# +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(trans_id, stmt_id) VALUES (27, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_1(trans_id, stmt_id) VALUES (27, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (27, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (27, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T N R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (27, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (27, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T N R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(trans_id, stmt_id) VALUES (28, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_5(trans_id, stmt_id) VALUES (28, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (28, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (28, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T N-trig R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (28, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (28, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T N-trig R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(trans_id, stmt_id) VALUES (29, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b- +SELECT fc_i_nt_5_suc (29, 4); +fc_i_nt_5_suc (29, 4) +fc_i_nt_5_suc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(29,4) +-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (29, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T N-func R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(29,4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (29, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T N-func R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(trans_id, stmt_id) VALUES (30, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b- +CALL pc_i_nt_5_suc (30, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',30), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',30), NAME_CONST('in_stmt_id',1) + 1) +-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (30, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T N-proc R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',30), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',30), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (30, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T N-proc R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_5(trans_id, stmt_id) VALUES (31, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_1(trans_id, stmt_id) VALUES (31, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (31, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (31, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-trig N R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (31, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (31, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T-trig N R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_5(trans_id, stmt_id) VALUES (32, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_5(trans_id, stmt_id) VALUES (32, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (32, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (32, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-trig N-trig R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (32, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (32, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T-trig N-trig R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_5(trans_id, stmt_id) VALUES (33, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b- +SELECT fc_i_nt_5_suc (33, 4); +fc_i_nt_5_suc (33, 4) +fc_i_nt_5_suc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(33,4) +-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (33, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-trig N-func R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(33,4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (33, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T-trig N-func R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-trig << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_5(trans_id, stmt_id) VALUES (34, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-trig << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b- +CALL pc_i_nt_5_suc (34, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',34), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',34), NAME_CONST('in_stmt_id',1) + 1) +-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (34, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-trig N-proc R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',34), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',34), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES (34, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T-trig N-proc R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b- +SELECT fc_i_tt_5_suc (35, 2); +fc_i_tt_5_suc (35, 2) +fc_i_tt_5_suc +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_1(trans_id, stmt_id) VALUES (35, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (35, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(35,2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-func N R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (35, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(35,2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T-func N R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b- +SELECT fc_i_tt_5_suc (36, 2); +fc_i_tt_5_suc (36, 2) +fc_i_tt_5_suc +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_5(trans_id, stmt_id) VALUES (36, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (36, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(36,2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-func N-trig R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (36, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(36,2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T-func N-trig R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b- +SELECT fc_i_tt_5_suc (37, 2); +fc_i_tt_5_suc (37, 2) +fc_i_tt_5_suc +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b- +SELECT fc_i_nt_5_suc (37, 4); +fc_i_nt_5_suc (37, 4) +fc_i_nt_5_suc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(37,4) +-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(37,2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-func N-func R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(37,4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(37,2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T-func N-func R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-func << -b-b-b-b-b-b-b-b-b-b-b- +SELECT fc_i_tt_5_suc (38, 2); +fc_i_tt_5_suc (38, 2) +fc_i_tt_5_suc +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-func << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b- +CALL pc_i_nt_5_suc (38, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',38), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',38), NAME_CONST('in_stmt_id',1) + 1) +-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(38,2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-func N-proc R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',38), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',38), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_tt_5_suc`(38,2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T-func N-proc R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b- +CALL pc_i_tt_5_suc (39, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_1(trans_id, stmt_id) VALUES (39, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (39, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',39), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',39), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-proc N R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (39, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',39), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',39), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T-proc N R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b- +CALL pc_i_tt_5_suc (40, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-trig << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_5(trans_id, stmt_id) VALUES (40, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (40, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N-trig << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',40), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',40), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-proc N-trig R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES (40, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',40), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',40), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T-proc N-trig R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b- +CALL pc_i_tt_5_suc (41, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-func << -b-b-b-b-b-b-b-b-b-b-b- +SELECT fc_i_nt_5_suc (41, 4); +fc_i_nt_5_suc (41, 4) +fc_i_nt_5_suc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(41,4) +-e-e-e-e-e-e-e-e-e-e-e- >> N-func << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',41), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',41), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-proc N-func R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; SELECT `test`.`fc_i_nt_5_suc`(41,4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',41), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',41), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T-proc N-func R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T-proc << -b-b-b-b-b-b-b-b-b-b-b- +CALL pc_i_tt_5_suc (42, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T-proc << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N-proc << -b-b-b-b-b-b-b-b-b-b-b- +CALL pc_i_nt_5_suc (42, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',42), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',42), NAME_CONST('in_stmt_id',1) + 1) +-e-e-e-e-e-e-e-e-e-e-e- >> N-proc << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',42), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',42), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T-proc N-proc R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',42), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO nt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',42), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',42), NAME_CONST('in_stmt_id',1)) +master-bin.000001 # Query # # use `test`; INSERT INTO tt_5(trans_id, stmt_id) VALUES ( NAME_CONST('p_trans_id',42), NAME_CONST('in_stmt_id',1) + 1) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T-proc N-proc R << -e-e-e-e-e-e-e-e-e-e-e- + + + + + +# +#4.e) Generates in the binlog what follows if T* fails: +# --> STMT "B N C" entry, format S. +# Otherwise, what follows if N* fails and a N-Table is changed: +# --> STMT "N" entries, format S. +# +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> eT << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(trans_id, stmt_id) VALUES (26, 2); +Got one of the listed errors +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> eT << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_1(trans_id, stmt_id) VALUES (43, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (43, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B eT N R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (43, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> B eT N R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> Te << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(trans_id, stmt_id) VALUES (44, 2), (26, 2); +Got one of the listed errors +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> Te << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> N << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_1(trans_id, stmt_id) VALUES (44, 4); +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (44, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> N << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B Te N R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (44, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> B Te N R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(trans_id, stmt_id) VALUES (45, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> eN << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_1(trans_id, stmt_id) VALUES (44, 4); +Got one of the listed errors +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> eN << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T eN R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B T eN R << -e-e-e-e-e-e-e-e-e-e-e- + +-b-b-b-b-b-b-b-b-b-b-b- >> B << -b-b-b-b-b-b-b-b-b-b-b- +BEGIN; +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> B << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> T << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO tt_1(trans_id, stmt_id) VALUES (46, 2); +Log_name Pos Event_type Server_id End_log_pos Info +-e-e-e-e-e-e-e-e-e-e-e- >> T << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> Ne << -b-b-b-b-b-b-b-b-b-b-b- +INSERT INTO nt_1(trans_id, stmt_id) VALUES (46, 4), (44, 4); +Got one of the listed errors +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (46, 4), (44, 4) +-e-e-e-e-e-e-e-e-e-e-e- >> Ne << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> R << -b-b-b-b-b-b-b-b-b-b-b- +ROLLBACK; +Warnings: +Warning 1196 Some non-transactional changed tables couldn't be rolled back +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (46, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> R << -e-e-e-e-e-e-e-e-e-e-e- +-b-b-b-b-b-b-b-b-b-b-b- >> B T Ne R << -b-b-b-b-b-b-b-b-b-b-b- +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; INSERT INTO nt_1(trans_id, stmt_id) VALUES (46, 4), (44, 4) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `test`; INSERT INTO tt_1(trans_id, stmt_id) VALUES (46, 2) +master-bin.000001 # Query # # ROLLBACK +-e-e-e-e-e-e-e-e-e-e-e- >> B T Ne R << -e-e-e-e-e-e-e-e-e-e-e- + +################################################################################### +# CHECK CONSISTENCY +################################################################################### +################################################################################### +# CLEAN +################################################################################### diff --git a/mysql-test/suite/rpl/t/rpl_stm_binlog_direct-master.opt b/mysql-test/suite/rpl/t/rpl_stm_binlog_direct-master.opt new file mode 100644 index 00000000000..561902d0bd9 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_stm_binlog_direct-master.opt @@ -0,0 +1 @@ +--binlog-direct-non-transactional-updates diff --git a/mysql-test/suite/rpl/t/rpl_stm_binlog_direct.test b/mysql-test/suite/rpl/t/rpl_stm_binlog_direct.test new file mode 100644 index 00000000000..f0c36c7b40c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_stm_binlog_direct.test @@ -0,0 +1,230 @@ +################################################################################ +# This test case checks if the option "binlog-direct-non-transactional-updates" +# makes non-transactional changes in the statement format to be written to the +# binary log as soon as the statement commits. +# +# In what follows, we use the include file rpl_mixing_engines.inc to generate +# sql commands from a format string. The format string consists of a sequence of +# 'codes' separated by spaces. Before it set of commands, we paste the expected +# sequence in the binary log. The following codes exist: +# +# - Define the scope of a transaction: +# B - Begin. +# C - Commit. +# R - Rollback. +# +# - Change only T-Tables: +# T - Updates a T-Table. +# T-trig - Updates T-Tables through a trigger. +# T-func - Updates T-Tables through a function. +# T-proc - Updates T-Tables through a procedure. +# eT - Fails while updating the first tuple in a T-Table. +# Te - Fails while updating an n-tuple (n > 1) in a T-Table. +# Te-trig - Fails while updating an n-tuple (n > 1) in a T-Table. +# Te-func - Fails while updating an n-tuple (n > 1) in a T-Table. +# +# - Change only N-Tables +# N - Updates a N-Table. +# N-trig - Updates N-Tables through a trigger. +# N-func - Updates N-Tables through a function. +# N-proc - Updates N-Tables through a procedure. +# eN - Fails while updating the first tuple in a N-Table. +# Ne - Fails while updating an n-tuple (n > 1) in a N-Table. +# Ne-trig - Fails while updating an n-tuple (n > 1) in a N-Table. +# Ne-func - Fails while updating an n-tuple (n > 1) in a N-Table. +################################################################################ + +--source include/have_binlog_format_statement.inc +--source include/master-slave.inc +--source include/have_innodb.inc + +set @@session.binlog_direct_non_transactional_updates= TRUE; + +--echo ######################################################################### +--echo # CONFIGURATION +--echo ######################################################################### + +--let $engine_type= Innodb +SET @commands= 'configure'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +--echo ######################################################################### +--echo # 1 - BINLOG ORDER +--echo ######################################################################### +connection master; + +--echo +--echo +--echo +--echo +--echo # +--echo #3) Generates in the binlog what follows: +--echo # --> STMT "N B T C" entries, format S. +--echo # +SET @commands= 'B T N C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T N-trig C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T N-func C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T N-proc C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-trig N C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-trig N-trig C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-trig N-func C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-trig N-proc C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-func N C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-func N-trig C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-func N-func C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-func N-proc C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-proc N C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-proc N-trig C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-proc N-func C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-proc N-proc C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #3.e) Generates in the binlog what follows if T-* fails: +--echo # --> STMT "N" entry, format S. +--echo # Otherwise, what follows if N-* fails and a N-Table is changed: +--echo # --> STMT "N B T C" entries, format S. +--echo # +SET @commands= 'B eT N C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B Te N C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T eN C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T Ne C'; +--source extra/rpl_tests/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #4) Generates in the binlog what follows: +--echo # --> STMT "N B T R" entries, format S. +--echo # +SET @commands= 'B T N R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T N-trig R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T N-func R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T N-proc R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-trig N R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-trig N-trig R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-trig N-func R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-trig N-proc R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-func N R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-func N-trig R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-func N-func R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-func N-proc R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-proc N R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-proc N-trig R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-proc N-func R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T-proc N-proc R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + + +--echo +--echo +--echo +--echo +--echo # +--echo #4.e) Generates in the binlog what follows if T* fails: +--echo # --> STMT "B N C" entry, format S. +--echo # Otherwise, what follows if N* fails and a N-Table is changed: +--echo # --> STMT "N" entries, format S. +--echo # +SET @commands= 'B eT N R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B Te N R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T eN R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + +SET @commands= 'B T Ne R'; +--source extra/rpl_tests/rpl_mixing_engines.inc + + +--echo ################################################################################### +--echo # CHECK CONSISTENCY +--echo ################################################################################### +connection master; +sync_slave_with_master; + +--exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-nmt-master.sql +--exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info test > $MYSQLTEST_VARDIR/tmp/test-nmt-slave.sql +--diff_files $MYSQLTEST_VARDIR/tmp/test-nmt-master.sql $MYSQLTEST_VARDIR/tmp/test-nmt-slave.sql + +--echo ################################################################################### +--echo # CLEAN +--echo ################################################################################### +SET @commands= 'clean'; +--source extra/rpl_tests/rpl_mixing_engines.inc diff --git a/sql/log.cc b/sql/log.cc index 36d57271a7d..bc9efd75ea2 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -4284,12 +4284,20 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) #if defined(USING_TRANSACTIONS) /* Should we write to the binlog cache or to the binlog on disk? + Write to the binlog cache if: - - it is already not empty (meaning we're in a transaction; note that the - present event could be about a non-transactional table, but still we need - to write to the binlog cache in that case to handle updates to mixed - trans/non-trans table types the best possible in binlogging) - - or if the event asks for it (cache_stmt == TRUE). + 1 - a transactional engine/table is updated (stmt_has_updated_trans_table == TRUE); + 2 - or the event asks for it (cache_stmt == TRUE); + 3 - or the cache is already not empty (meaning we're in a transaction; + note that the present event could be about a non-transactional table, but + still we need to write to the binlog cache in that case to handle updates + to mixed trans/non-trans table types). + + Write to the binlog on disk if only a non-transactional engine is + updated and: + 1 - the binlog cache is empty or; + 2 - --binlog-direct-non-transactional-updates is set and we are about to + use the statement format. When using the row format (cache_stmt == TRUE). */ if (opt_using_transactions && thd) { @@ -4300,8 +4308,9 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) (binlog_trx_data*) thd_get_ha_data(thd, binlog_hton); IO_CACHE *trans_log= &trx_data->trans_log; my_off_t trans_log_pos= my_b_tell(trans_log); - if (event_info->get_cache_stmt() || trans_log_pos != 0 || - stmt_has_updated_trans_table(thd)) + if (event_info->get_cache_stmt() || stmt_has_updated_trans_table(thd) || + (!thd->variables.binlog_direct_non_trans_update && + trans_log_pos != 0)) { DBUG_PRINT("info", ("Using trans_log: cache: %d, trans_log_pos: %lu", event_info->get_cache_stmt(), diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7bb357827c8..242acd28ecc 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5727,7 +5727,8 @@ enum options_mysqld OPT_SLAVE_EXEC_MODE, OPT_GENERAL_LOG_FILE, OPT_SLOW_QUERY_LOG_FILE, - OPT_IGNORE_BUILTIN_INNODB + OPT_IGNORE_BUILTIN_INNODB, + OPT_BINLOG_DIRECT_NON_TRANS_UPDATE }; @@ -7071,6 +7072,10 @@ The minimum value for this variable is 4096.", (uchar**) &max_system_variables.net_wait_timeout, 0, GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT), 0, 1, 0}, + {"binlog-direct-non-transactional-updates", OPT_BINLOG_DIRECT_NON_TRANS_UPDATE, + "Causes updates to non-transactional engines using statement format to be written directly to binary log. Before using this option make sure that there are no dependencies between transactional and non-transactional tables such as in the statement INSERT INTO t_myisam SELECT * FROM t_innodb; otherwise, slaves may diverge from the master.", + (uchar**) &global_system_variables.binlog_direct_non_trans_update, (uchar**) &max_system_variables.binlog_direct_non_trans_update, 0, GET_BOOL, NO_ARG, 0, + 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; diff --git a/sql/set_var.cc b/sql/set_var.cc index 3c6b259045d..e06ad9dcc59 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -181,6 +181,8 @@ static sys_var_long_ptr sys_binlog_cache_size(&vars, "binlog_cache_size", &binlog_cache_size); static sys_var_thd_binlog_format sys_binlog_format(&vars, "binlog_format", &SV::binlog_format); +static sys_var_thd_bool sys_binlog_direct_non_trans_update(&vars, "binlog_direct_non_transactional_updates", + &SV::binlog_direct_non_trans_update); static sys_var_thd_ulong sys_bulk_insert_buff_size(&vars, "bulk_insert_buffer_size", &SV::bulk_insert_buff_size); static sys_var_const_os sys_character_sets_dir(&vars, diff --git a/sql/sql_class.h b/sql/sql_class.h index 8acc03f929d..56d31be79c7 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -353,6 +353,7 @@ struct system_variables ulong ndb_index_stat_cache_entries; ulong ndb_index_stat_update_freq; ulong binlog_format; // binlog format for this thd (see enum_binlog_format) + my_bool binlog_direct_non_trans_update; /* In slave thread we need to know in behalf of which thread the query is being run to replicate temp tables properly From 45d2799a15a2bdde386b113cd6fcab915d4984d2 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 20 Jan 2010 22:21:18 -0200 Subject: [PATCH 113/157] Apply patch on behalf of the NDB team: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 3321 Magnus BlÃ¥udd 2010-01-05 BUG#44840 - ndbapi compiler warning - type qualifier ignored for function return type - Remove the "const" - NOTE! This is an ABI incompatible change for some C++ compilers, NdbApi applications using any of the four changed functions may need a recompile if it's using dynamic linking. --- storage/ndb/include/ndbapi/NdbEventOperation.hpp | 8 ++++---- storage/ndb/include/ndbapi/NdbOperation.hpp | 4 ++-- storage/ndb/src/ndbapi/NdbEventOperation.cpp | 8 ++++---- storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp | 8 ++++---- storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp | 8 ++++---- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/storage/ndb/include/ndbapi/NdbEventOperation.hpp b/storage/ndb/include/ndbapi/NdbEventOperation.hpp index 437088d2893..0f98a4debef 100644 --- a/storage/ndb/include/ndbapi/NdbEventOperation.hpp +++ b/storage/ndb/include/ndbapi/NdbEventOperation.hpp @@ -178,22 +178,22 @@ public: /** * Check if table name has changed, for event TE_ALTER */ - const bool tableNameChanged() const; + bool tableNameChanged() const; /** * Check if table frm has changed, for event TE_ALTER */ - const bool tableFrmChanged() const; + bool tableFrmChanged() const; /** * Check if table fragmentation has changed, for event TE_ALTER */ - const bool tableFragmentationChanged() const; + bool tableFragmentationChanged() const; /** * Check if table range partition list name has changed, for event TE_ALTER */ - const bool tableRangeListChanged() const; + bool tableRangeListChanged() const; /** * Retrieve the GCI of the latest retrieved event diff --git a/storage/ndb/include/ndbapi/NdbOperation.hpp b/storage/ndb/include/ndbapi/NdbOperation.hpp index 78dbadfd7ab..713c29f028d 100644 --- a/storage/ndb/include/ndbapi/NdbOperation.hpp +++ b/storage/ndb/include/ndbapi/NdbOperation.hpp @@ -779,7 +779,7 @@ public: /** * Get the type of access for this operation */ - const Type getType() const; + Type getType() const; /** @} *********************************************************************/ @@ -1135,7 +1135,7 @@ Return Value Return the Type. Remark: Gets type of access. ******************************************************************************/ inline -const NdbOperation::Type +NdbOperation::Type NdbOperation::getType() const { return m_type; diff --git a/storage/ndb/src/ndbapi/NdbEventOperation.cpp b/storage/ndb/src/ndbapi/NdbEventOperation.cpp index 5c6ed562dcc..1353ca40e95 100644 --- a/storage/ndb/src/ndbapi/NdbEventOperation.cpp +++ b/storage/ndb/src/ndbapi/NdbEventOperation.cpp @@ -96,22 +96,22 @@ NdbEventOperation::hasError() const return m_impl.m_has_error; } -const bool NdbEventOperation::tableNameChanged() const +bool NdbEventOperation::tableNameChanged() const { return m_impl.tableNameChanged(); } -const bool NdbEventOperation::tableFrmChanged() const +bool NdbEventOperation::tableFrmChanged() const { return m_impl.tableFrmChanged(); } -const bool NdbEventOperation::tableFragmentationChanged() const +bool NdbEventOperation::tableFragmentationChanged() const { return m_impl.tableFragmentationChanged(); } -const bool NdbEventOperation::tableRangeListChanged() const +bool NdbEventOperation::tableRangeListChanged() const { return m_impl.tableRangeListChanged(); } diff --git a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp index dff953923fe..ed60650e33e 100644 --- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp +++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp @@ -658,22 +658,22 @@ NdbEventOperationImpl::stop() DBUG_RETURN(r); } -const bool NdbEventOperationImpl::tableNameChanged() const +bool NdbEventOperationImpl::tableNameChanged() const { return (bool)AlterTableReq::getNameFlag(m_change_mask); } -const bool NdbEventOperationImpl::tableFrmChanged() const +bool NdbEventOperationImpl::tableFrmChanged() const { return (bool)AlterTableReq::getFrmFlag(m_change_mask); } -const bool NdbEventOperationImpl::tableFragmentationChanged() const +bool NdbEventOperationImpl::tableFragmentationChanged() const { return (bool)AlterTableReq::getFragDataFlag(m_change_mask); } -const bool NdbEventOperationImpl::tableRangeListChanged() const +bool NdbEventOperationImpl::tableRangeListChanged() const { return (bool)AlterTableReq::getRangeListFlag(m_change_mask); } diff --git a/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp b/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp index 3d71146588d..c027226584c 100644 --- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp +++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp @@ -361,10 +361,10 @@ public: NdbBlob *getBlobHandle(const NdbColumnImpl *, int n); int readBlobParts(char* buf, NdbBlob* blob, Uint32 part, Uint32 count); int receive_event(); - const bool tableNameChanged() const; - const bool tableFrmChanged() const; - const bool tableFragmentationChanged() const; - const bool tableRangeListChanged() const; + bool tableNameChanged() const; + bool tableFrmChanged() const; + bool tableFragmentationChanged() const; + bool tableRangeListChanged() const; Uint64 getGCI(); Uint32 getAnyValue() const; Uint64 getLatestGCI(); From 9eae1881b384592e8fc13a78000071a08fe7370f Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Wed, 20 Jan 2010 22:22:20 -0200 Subject: [PATCH 114/157] Apply patch on behalf of Magnus: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 3325 Magnus BlÃ¥udd 2010-01-05 Bug #49860 new compiler warning ha_archive - fix compiler warning by casting to ulong --- storage/archive/ha_archive.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 4648ca798da..42ff9daa77e 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -1490,7 +1490,7 @@ int ha_archive::info(uint flag) stats.create_time= (ulong) file_stat.st_ctime; stats.update_time= (ulong) file_stat.st_mtime; stats.mean_rec_length= stats.records ? - stats.data_file_length / stats.records : table->s->reclength; + ulong(stats.data_file_length / stats.records) : table->s->reclength; stats.max_data_file_length= MAX_FILE_SIZE; } stats.delete_length= 0; From 132b46e96eb48b8d9d993583ed7b9ecd87e53674 Mon Sep 17 00:00:00 2001 From: Magne Mahre Date: Thu, 21 Jan 2010 09:10:05 +0100 Subject: [PATCH 115/157] WL#5154 Remove deprecated 4.1 features Several items said to be deprecated in the 4.1 manual have never been removed. This worklog adds deprecation warnings when these items are used, and warns the user that the items will be removed in MySQL 5.6. A couple of previously deprecation decision have been reversed (see single file comments) client/client_priv.h: Macro similar to the one in the server (mysql_priv.h) for printing a deprecation warning message client/mysql.cc: no-auto-rehash will not be deprecated skip-line-numbers will not be deprecated skip-column-names will not be deprecated no-pager is deprecated set-variable is deprecated no-named-commands is deprecated client/mysqladmin.cc: set-variable is deprecated client/mysqlbinlog.cc: position is deprecated client/mysqldump.c: first-slave is deprecated no-set-names is deprecated set-variable is deprecated mysql-test/r/mysqlbinlog.result: Adding the [Warning] to the test case, just to show that the deprecation works. The test case will be changed in Celosia to use --start-position. mysys/my_getopt.c: set-variable (include -O) is deprecated scripts/mysqld_multi.sh: Warning for mysqld_multi sql/mysqld.cc: default-collation is deprecated log-bin-trust-routine-creators is deprecated set-variable is deprecated default-character-set is deprecated safe-show-database is deprecated sql/share/errmsg.txt: Added version number for sql_log_update deprecation message. --- client/client_priv.h | 12 +++++++++++- client/mysql.cc | 17 +++++++++++++---- client/mysqladmin.cc | 3 +++ client/mysqlbinlog.cc | 8 ++++++-- client/mysqldump.c | 11 ++++++++--- mysql-test/r/func_time.result | 10 +++++----- mysql-test/r/mysqlbinlog.result | 3 +++ mysql-test/r/variables.result | 2 +- mysys/my_getopt.c | 9 +++++++++ scripts/mysqld_multi.sh | 3 +++ sql/mysql_priv.h | 4 ++++ sql/mysqld.cc | 22 ++++++++++++++++++++-- sql/set_var.cc | 2 +- sql/share/errmsg.txt | 8 ++++---- sql/sql_yacc.yy | 2 +- 15 files changed, 92 insertions(+), 24 deletions(-) diff --git a/client/client_priv.h b/client/client_priv.h index 06145232995..9d2fc2be141 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -31,6 +31,15 @@ # endif #endif +/* Version numbers for deprecation messages */ +#define VER_CELOSIA "5.6" + +#define WARN_DEPRECATED(Ver,Old,New) \ + do { \ + printf("Warning: The option '%s' is deprecated and will be removed " \ + "in MySQL %s. Please use %s instead.\n", (Old), (Ver), (New)); \ + } while(0); + enum options_client { OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, @@ -49,7 +58,7 @@ enum options_client OPT_SHARED_MEMORY_BASE_NAME, OPT_FRM, OPT_SKIP_OPTIMIZATION, OPT_COMPATIBLE, OPT_RECONNECT, OPT_DELIMITER, OPT_SECURE_AUTH, OPT_OPEN_FILES_LIMIT, OPT_SET_CHARSET, OPT_CREATE_OPTIONS, OPT_SERVER_ARG, - OPT_START_POSITION, OPT_STOP_POSITION, OPT_START_DATETIME, OPT_STOP_DATETIME, + OPT_POSITION, OPT_STOP_POSITION, OPT_START_DATETIME, OPT_STOP_DATETIME, OPT_SIGINT_IGNORE, OPT_HEXBLOB, OPT_ORDER_BY_PRIMARY, OPT_COUNT, #ifdef HAVE_NDBCLUSTER_DB OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING, @@ -80,5 +89,6 @@ enum options_client OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT, OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE, OPT_WRITE_BINLOG, OPT_DUMP_DATE, + OPT_FIRST_SLAVE, OPT_MAX_CLIENT_OPTION }; diff --git a/client/mysql.cc b/client/mysql.cc index b3854636bb2..b3b73fdb468 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -54,6 +54,9 @@ static char *server_version= NULL; /* Array of options to pass to libemysqld */ #define MAX_SERVER_ARGS 64 +/* Version numbers for deprecation messages */ +#define VER_CELOSIA "5.6" + void* sql_alloc(unsigned size); // Don't use mysqld alloc for these void sql_element_free(void *ptr); #include "sql_string.h" @@ -1343,7 +1346,7 @@ static struct my_option my_long_options[] = (uchar**) &opt_rehash, (uchar**) &opt_rehash, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"no-auto-rehash", 'A', - "No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mysql and disables rehashing on reconnect. WARNING: options deprecated; use --disable-auto-rehash instead.", + "No automatic rehashing. One has to use 'rehash' to get table and field completion. This gives a quicker start of mysql and disables rehashing on reconnect.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"batch", 'B', "Don't use history file. Disable interactive behavior. (Enables --silent)", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -1412,7 +1415,7 @@ static struct my_option my_long_options[] = {"line-numbers", OPT_LINE_NUMBERS, "Write line numbers for errors.", (uchar**) &line_numbers, (uchar**) &line_numbers, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, - {"skip-line-numbers", 'L', "Don't write line number for errors. WARNING: -L is deprecated, use long version of this option instead.", 0, 0, 0, GET_NO_ARG, + {"skip-line-numbers", 'L', "Don't write line number for errors.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"unbuffered", 'n', "Flush buffer after each query.", (uchar**) &unbuffered, (uchar**) &unbuffered, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -1420,7 +1423,7 @@ static struct my_option my_long_options[] = (uchar**) &column_names, (uchar**) &column_names, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"skip-column-names", 'N', - "Don't write column names in results. WARNING: -N is deprecated, use long version of this options instead.", + "Don't write column names in results.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"set-variable", 'O', "Change the value of a variable. Please note that this option is deprecated; you can set variables directly with --variable-name=value.", @@ -1650,7 +1653,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } break; case OPT_NOPAGER: - printf("WARNING: option deprecated; use --disable-pager instead.\n"); + WARN_DEPRECATED(VER_CELOSIA, "--no-pager", "--disable-pager"); opt_nopager= 1; break; case OPT_MYSQL_PROTOCOL: @@ -1696,12 +1699,18 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), if (!(status.line_buff= batch_readline_command(status.line_buff, argument))) return 1; break; + case 'g': + WARN_DEPRECATED(VER_CELOSIA, "-g, --no-named-commands", "--skip-named-commands"); + break; case 'o': if (argument == disabled_my_option) one_database= 0; else one_database= skip_updates= 1; break; + case 'O': + WARN_DEPRECATED(VER_CELOSIA, "-O, --set-variable", "--variable-name=value"); + break; case 'p': if (argument == disabled_my_option) argument= (char*) ""; // Don't require password diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 2b93c149523..04e25fcf1ff 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -282,6 +282,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), charsets_dir = argument; #endif break; + case 'O': + WARN_DEPRECATED(VER_CELOSIA, "--set-variable", "--variable-name=value"); + break; case OPT_MYSQL_PROTOCOL: opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, opt->name); diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index f55dc75df5d..1c0f6e5f96a 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -41,6 +41,7 @@ #define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES) + char server_version[SERVER_VERSION_LENGTH]; ulong server_id = 0; @@ -1060,7 +1061,7 @@ static struct my_option my_long_options[] = "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").", (uchar**) &port, (uchar**) &port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"position", 'j', "Deprecated. Use --start-position instead.", + {"position", OPT_POSITION, "Deprecated. Use --start-position instead.", (uchar**) &start_position, (uchar**) &start_position, 0, GET_ULL, REQUIRED_ARG, BIN_LOG_HEADER_SIZE, BIN_LOG_HEADER_SIZE, /* COM_BINLOG_DUMP accepts only 4 bytes for the position */ @@ -1103,7 +1104,7 @@ static struct my_option my_long_options[] = "(you should probably use quotes for your shell to set it properly).", (uchar**) &start_datetime_str, (uchar**) &start_datetime_str, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"start-position", OPT_START_POSITION, + {"start-position", 'j', "Start reading the binlog at position N. Applies to the first binlog " "passed on the command line.", (uchar**) &start_position, (uchar**) &start_position, 0, GET_ULL, @@ -1314,6 +1315,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'R': remote_opt= 1; break; + case OPT_POSITION: + WARN_DEPRECATED(VER_CELOSIA, "--position", "--start-position"); + break; case OPT_MYSQL_PROTOCOL: opt_protocol= find_type_or_exit(argument, &sql_protocol_typelib, opt->name); diff --git a/client/mysqldump.c b/client/mysqldump.c index 56d6c12981f..25a8d7b0f6f 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -282,7 +282,7 @@ static struct my_option my_long_options[] = (uchar**) &opt_enclosed, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0 ,0, 0}, {"fields-escaped-by", OPT_ESC, "Fields in the i.file are escaped by ...", (uchar**) &escaped, (uchar**) &escaped, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"first-slave", 'x', "Deprecated, renamed to --lock-all-tables.", + {"first-slave", OPT_FIRST_SLAVE, "Deprecated, renamed to --lock-all-tables.", (uchar**) &opt_lock_all_tables, (uchar**) &opt_lock_all_tables, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"flush-logs", 'F', "Flush logs file in server before starting dump. " @@ -366,8 +366,7 @@ static struct my_option my_long_options[] = NO_ARG, 0, 0, 0, 0, 0, 0}, {"no-data", 'd', "No row information.", (uchar**) &opt_no_data, (uchar**) &opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"no-set-names", 'N', - "Deprecated. Use --skip-set-charset instead.", + {"no-set-names", 'N',"Suppress the SET NAMES statement", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"opt", OPT_OPTIMIZE, "Same as --add-drop-table, --add-locks, --create-options, --quick, --extended-insert, --lock-tables, --set-charset, and --disable-keys. Enabled by default, disable with --skip-opt.", @@ -760,6 +759,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case '?': usage(); exit(0); + case 'O': + WARN_DEPRECATED(VER_CELOSIA, "--set-variable", "--variable-name=value"); + break; + case (int) OPT_FIRST_SLAVE: + WARN_DEPRECATED(VER_CELOSIA, "--first-slave", "--lock-all-tables"); + break; case (int) OPT_MASTER_DATA: if (!argument) /* work like in old versions */ opt_master_data= MYSQL_OPT_MASTER_DATA_EFFECTIVE_SQL; diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 0fa143d95bc..2ac549a5abd 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -682,7 +682,7 @@ select timestampadd(SQL_TSI_FRAC_SECOND, 1, date) from t1; timestampadd(SQL_TSI_FRAC_SECOND, 1, date) 2003-01-02 00:00:00.000001 Warnings: -Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 6.2. Please use MICROSECOND instead +Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 5.6. Please use MICROSECOND instead select timestampdiff(MONTH, '2001-02-01', '2001-05-01') as a; a 3 @@ -717,7 +717,7 @@ select timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05 a 7689538999999 Warnings: -Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 6.2. Please use MICROSECOND instead +Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 5.6. Please use MICROSECOND instead select timestampdiff(SQL_TSI_DAY, '1986-02-01', '1986-03-01') as a1, timestampdiff(SQL_TSI_DAY, '1900-02-01', '1900-03-01') as a2, timestampdiff(SQL_TSI_DAY, '1996-02-01', '1996-03-01') as a3, @@ -1088,7 +1088,7 @@ timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12: id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 6.2. Please use MICROSECOND instead +Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 5.6. Please use MICROSECOND instead Note 1003 select timestampdiff(WEEK,'2001-02-01','2001-05-01') AS `a1`,timestampdiff(SECOND_FRAC,'2001-02-01 12:59:59.120000','2001-05-01 12:58:58.119999') AS `a2` select time_format('100:00:00', '%H %k %h %I %l'); time_format('100:00:00', '%H %k %h %I %l') @@ -1287,12 +1287,12 @@ SELECT TIMESTAMPADD(FRAC_SECOND, 1, '2008-02-18'); TIMESTAMPADD(FRAC_SECOND, 1, '2008-02-18') 2008-02-18 00:00:00.000001 Warnings: -Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 6.2. Please use MICROSECOND instead +Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 5.6. Please use MICROSECOND instead SELECT TIMESTAMPDIFF(FRAC_SECOND, '2008-02-17', '2008-02-18'); TIMESTAMPDIFF(FRAC_SECOND, '2008-02-17', '2008-02-18') 86400000000 Warnings: -Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 6.2. Please use MICROSECOND instead +Warning 1287 The syntax 'FRAC_SECOND' is deprecated and will be removed in MySQL 5.6. Please use MICROSECOND instead SELECT DATE_ADD('2008-02-18', INTERVAL 1 FRAC_SECOND); 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 'FRAC_SECOND)' at line 1 SELECT DATE_SUB('2008-02-18', INTERVAL 1 FRAC_SECOND); diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index 9d4fde96d18..f5c40202101 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -93,6 +93,7 @@ ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- --position -- +Warning: The option '--position' is deprecated and will be removed in MySQL 5.6. Please use --start-position instead. /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -193,6 +194,7 @@ ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- --position -- +Warning: The option '--position' is deprecated and will be removed in MySQL 5.6. Please use --start-position instead. /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -233,6 +235,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +Warning: The option '--position' is deprecated and will be removed in MySQL 5.6. Please use --start-position instead. /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 541b2b2fb86..7f45046fab5 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -566,7 +566,7 @@ set sql_log_bin=1; set sql_log_off=1; set sql_log_update=1; Warnings: -Note 1315 The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been ignored +Note 1315 The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been ignored. This option will be removed in MySQL 5.6. set sql_low_priority_updates=1; set sql_max_join_size=200; select @@sql_max_join_size,@@max_join_size; diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index e561d74f4d1..fc5662812b0 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -146,6 +146,10 @@ int handle_options(int *argc, char ***argv, { /* --set-variable, or -O */ if (*cur_arg == 'O') { + my_getopt_error_reporter(WARNING_LEVEL, + "%s: Option '-O' is deprecated. " + "Use --variable-name=value instead.", + my_progname); must_be_var= 1; if (!(*++cur_arg)) /* If not -Ovar=# */ @@ -165,6 +169,11 @@ int handle_options(int *argc, char ***argv, } else if (!getopt_compare_strings(cur_arg, "-set-variable", 13)) { + my_getopt_error_reporter(WARNING_LEVEL, + "%s: Option '--set-variable' is deprecated. " + "Use --variable-name=value instead.", + my_progname); + must_be_var= 1; if (cur_arg[13] == '=') { diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh index 430c74874eb..528a1ca2e98 100644 --- a/scripts/mysqld_multi.sh +++ b/scripts/mysqld_multi.sh @@ -68,7 +68,10 @@ sub main # than a correct --defaults-extra-file option unshift @defaults_options, "--defaults-extra-file=$1"; + print "WARNING: --config-file is deprecated and will be removed\n"; + print "in MySQL 5.6. Please use --defaults-extra-file instead\n"; } + } } foreach (@defaults_options) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 2be3b8f1f20..76edbf1dea3 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -111,6 +111,10 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); #define PREV_BITS(type,A) ((type) (((type) 1 << (A)) -1)) #define all_bits_set(A,B) ((A) & (B) != (B)) +/* Version numbers for deprecation messages */ +#define VER_BETONY "5.5" +#define VER_CELOSIA "5.6" + #define WARN_DEPRECATED(Thd,Ver,Old,New) \ do { \ DBUG_ASSERT(strncmp(Ver, MYSQL_SERVER_VERSION, sizeof(Ver)-1) > 0); \ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 242acd28ecc..db0453dc364 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5603,6 +5603,7 @@ enum options_mysqld OPT_DISCONNECT_SLAVE_EVENT_COUNT, OPT_TC_HEURISTIC_RECOVER, OPT_ABORT_SLAVE_EVENT_COUNT, OPT_LOG_BIN_TRUST_FUNCTION_CREATORS, + OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD, OPT_ENGINE_CONDITION_PUSHDOWN, OPT_NDB_CONNECTSTRING, OPT_NDB_USE_EXACT_COUNT, OPT_NDB_USE_TRANSACTIONS, OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ, @@ -5683,6 +5684,7 @@ enum options_mysqld OPT_EXPIRE_LOGS_DAYS, OPT_GROUP_CONCAT_MAX_LEN, OPT_DEFAULT_COLLATION, + OPT_DEFAULT_COLLATION_OLD, OPT_CHARACTER_SET_CLIENT_HANDSHAKE, OPT_CHARACTER_SET_FILESYSTEM, OPT_LC_TIME_NAMES, @@ -5857,7 +5859,7 @@ struct my_option my_long_options[] = {"default-character-set", 'C', "Set the default character set (deprecated option, use --character-set-server instead).", (uchar**) &default_character_set_name, (uchar**) &default_character_set_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, - {"default-collation", OPT_DEFAULT_COLLATION, "Set the default collation (deprecated option, use --collation-server instead).", + {"default-collation", OPT_DEFAULT_COLLATION_OLD, "Set the default collation (deprecated option, use --collation-server instead).", (uchar**) &default_collation_name, (uchar**) &default_collation_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, {"default-storage-engine", OPT_STORAGE_ENGINE, @@ -5988,7 +5990,7 @@ each time the SQL thread starts.", compatibility; the behaviour was also changed to apply only to functions (and triggers). In a future release this old name could be removed. */ - {"log-bin-trust-routine-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS, + {"log-bin-trust-routine-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD, "(deprecated) Use log-bin-trust-function-creators.", (uchar**) &trust_function_creators, (uchar**) &trust_function_creators, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -7905,6 +7907,9 @@ mysqld_get_one_option(int optid, #endif opt_endinfo=1; /* unireg: memory allocation */ break; + case '0': + WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-long-format", "--log-short-format"); + break; case 'a': global_system_variables.sql_mode= fix_sql_mode(MODE_ANSI); global_system_variables.tx_isolation= ISO_SERIALIZABLE; @@ -7913,6 +7918,7 @@ mysqld_get_one_option(int optid, strmake(mysql_home,argument,sizeof(mysql_home)-1); break; case 'C': + WARN_DEPRECATED(NULL, VER_CELOSIA, "--default-character-set", "--character-set-server"); if (default_collation_name == compiled_default_collation_name) default_collation_name= 0; break; @@ -7935,6 +7941,9 @@ mysqld_get_one_option(int optid, case 'L': strmake(language, argument, sizeof(language)-1); break; + case 'O': + WARN_DEPRECATED(NULL, VER_CELOSIA, "--set-variable", "--variable-name=value"); + break; #ifdef HAVE_REPLICATION case OPT_SLAVE_SKIP_ERRORS: init_slave_skip_errors(argument); @@ -7969,6 +7978,15 @@ mysqld_get_one_option(int optid, test_flags= argument ? (uint) atoi(argument) : 0; opt_endinfo=1; break; + case (int) OPT_DEFAULT_COLLATION_OLD: + WARN_DEPRECATED(NULL, VER_CELOSIA, "--default-collation", "--collation-server"); + break; + case (int) OPT_SAFE_SHOW_DB: + WARN_DEPRECATED(NULL, VER_CELOSIA, "--safe-show-database", "GRANT SHOW DATABASES"); + break; + case (int) OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD: + WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-bin-trust-routine-creators", "--log-bin-trust-function-creators"); + break; case (int) OPT_BIG_TABLES: thd_startup_options|=OPTION_BIG_TABLES; break; diff --git a/sql/set_var.cc b/sql/set_var.cc index e06ad9dcc59..2c00d76b0f1 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -4139,7 +4139,7 @@ bool process_key_caches(process_key_cache_t func) void sys_var_trust_routine_creators::warn_deprecated(THD *thd) { - WARN_DEPRECATED(thd, "6.0", "@@log_bin_trust_routine_creators", + WARN_DEPRECATED(thd, VER_CELOSIA, "@@log_bin_trust_routine_creators", "'@@log_bin_trust_function_creators'"); } diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 6d1b7aaf1ee..06ce848399b 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5138,11 +5138,11 @@ ER_SP_BADSTATEMENT 0A000 eng "%s is not allowed in stored procedures" ger "%s ist in gespeicherten Prozeduren nicht erlaubt" ER_UPDATE_LOG_DEPRECATED_IGNORED 42000 - eng "The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been ignored" - ger "Das Update-Log ist veraltet und wurde durch das Binär-Log ersetzt. SET SQL_LOG_UPDATE wird ignoriert" + eng "The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been ignored. This option will be removed in MySQL 5.6." + ger "Das Update-Log ist veraltet und wurde durch das Binär-Log ersetzt. SET SQL_LOG_UPDATE wird ignoriert. Diese Option wird in MySQL 5.6 entfernt." ER_UPDATE_LOG_DEPRECATED_TRANSLATED 42000 - eng "The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN" - ger "Das Update-Log ist veraltet und wurde durch das Binär-Log ersetzt. SET SQL_LOG_UPDATE wurde in SET SQL_LOG_BIN übersetzt" + eng "The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN. This option will be removed in MySQL 5.6." + ger "Das Update-Log ist veraltet und wurde durch das Binär-Log ersetzt. SET SQL_LOG_UPDATE wurde in SET SQL_LOG_BIN übersetzt. Diese Option wird in MySQL 5.6 entfernt." ER_QUERY_INTERRUPTED 70100 eng "Query execution was interrupted" ger "Ausführung der Abfrage wurde unterbrochen" diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 6dc2becf664..8dc08f8425f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -8932,7 +8932,7 @@ interval_time_stamp: implementation without changing its resolution. */ - WARN_DEPRECATED(yythd, "6.2", "FRAC_SECOND", "MICROSECOND"); + WARN_DEPRECATED(yythd, VER_CELOSIA, "FRAC_SECOND", "MICROSECOND"); } ; From 1dafac6f35b23757cafe0ac1ef9f6b4edb28947d Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 2 Feb 2010 14:17:21 +0200 Subject: [PATCH 116/157] fixed various pb2 test failures on windows. --- mysql-test/r/bug46080.result | 4 ++-- mysql-test/t/bug46080.test | 4 ++-- sql/event_scheduler.cc | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) mode change 100644 => 100755 mysql-test/r/bug46080.result mode change 100644 => 100755 sql/event_scheduler.cc diff --git a/mysql-test/r/bug46080.result b/mysql-test/r/bug46080.result old mode 100644 new mode 100755 index 2173768cdad..602027be43e --- a/mysql-test/r/bug46080.result +++ b/mysql-test/r/bug46080.result @@ -2,8 +2,8 @@ # Bug #46080: group_concat(... order by) crashes server when # sort_buffer_size cannot allocate # -call mtr.add_suppression("Out of memory at line .*, 'my_alloc.c'"); -call mtr.add_suppression("needed .* byte .*k., memory in use: .* bytes .*k"); +call mtr.add_suppression("Out of memory at line .*, '.*my_alloc.c'"); +call mtr.add_suppression("needed .* byte (.*k)., memory in use: .* bytes (.*k)"); CREATE TABLE t1(a CHAR(255)); INSERT INTO t1 VALUES ('a'); SET @@SESSION.sort_buffer_size=5*16*1000000; diff --git a/mysql-test/t/bug46080.test b/mysql-test/t/bug46080.test index 8b4cee4d8b0..ed4a16fdf51 100644 --- a/mysql-test/t/bug46080.test +++ b/mysql-test/t/bug46080.test @@ -3,8 +3,8 @@ --echo # sort_buffer_size cannot allocate --echo # -call mtr.add_suppression("Out of memory at line .*, 'my_alloc.c'"); -call mtr.add_suppression("needed .* byte .*k., memory in use: .* bytes .*k"); +call mtr.add_suppression("Out of memory at line .*, '.*my_alloc.c'"); +call mtr.add_suppression("needed .* byte (.*k)., memory in use: .* bytes (.*k)"); CREATE TABLE t1(a CHAR(255)); INSERT INTO t1 VALUES ('a'); diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc old mode 100644 new mode 100755 index 8c0025f9ed4..706afb3e0ad --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -235,8 +235,9 @@ event_scheduler_thread(void *arg) if (!res) scheduler->run(thd); + DBUG_LEAVE; // Against gcc warnings my_thread_end(); - DBUG_RETURN(0); // Against gcc warnings + return 0; } From 2db684572ea716de462bf8d79f398dfcc130a8ff Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 2 Feb 2010 11:17:58 -0200 Subject: [PATCH 117/157] Fix for valgrind warning: check whether pointer was initialized. storage/myisammrg/ha_myisammrg.cc: myisam pointer is not relevant if a error was raised. --- storage/myisammrg/ha_myisammrg.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index e265dac2c82..8af776f5c5e 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -380,7 +380,7 @@ static MI_INFO *myisammrg_attach_children_callback(void *callback_param) my_errno= HA_ERR_WRONG_MRG_TABLE_DEF; } DBUG_PRINT("myrg", ("MyISAM handle: 0x%lx my_errno: %d", - (long) myisam, my_errno)); + my_errno ? NULL : (long) myisam, my_errno)); err: DBUG_RETURN(my_errno ? NULL : myisam); From 59f1be1b636e360c410c81de1c41a8c4a254077d Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Tue, 2 Feb 2010 16:38:44 +0300 Subject: [PATCH 118/157] Revert a patch for Bug#48231, which introduced valgrind warnings. Original revision: ------------------------------------------------------------ revision-id: li-bing.song@sun.com-20100130124925-o6sfex42b6noyc6x parent: joro@sun.com-20100129145427-0n79l9hnk0q43ajk committer: branch nick: mysql-5.1-bugteam timestamp: Sat 2010-01-30 20:49:25 +0800 message: Bug #48321 CURRENT_USER() incorrectly replicated for DROP/RENAME USER; REVOKE/GRANT; ALTER EVENT. The following statements support the CURRENT_USER() where a user is needed. DROP USER RENAME USER CURRENT_USER() ... GRANT ... TO CURRENT_USER() REVOKE ... FROM CURRENT_USER() ALTER DEFINER = CURRENT_USER() EVENT but, When these statements are binlogged, CURRENT_USER() just is binlogged as 'CURRENT_USER()', it is not expanded to the real user name. When slave executes the log event, 'CURRENT_USER()' is expand to the user of slave SQL thread, but SQL thread's user name always NULL. This breaks the replication. After this patch, All above statements are rewritten when they are binlogged. The CURRENT_USER() is expanded to the real user's name and host. ------------------------------------------------------------ --- .../extra/rpl_tests/rpl_current_user.test | 127 -- .../suite/rpl/r/rpl_binlog_grant.result | 42 +- mysql-test/suite/rpl/r/rpl_events.result | 42 - .../suite/rpl/r/rpl_innodb_mixed_dml.result | 4 +- mysql-test/suite/rpl/r/rpl_sp.result | 16 +- mysql-test/suite/rpl/r/rpl_user.result | 1755 +---------------- mysql-test/suite/rpl/t/rpl_binlog_grant.test | 8 +- mysql-test/suite/rpl/t/rpl_events.test | 82 - mysql-test/suite/rpl/t/rpl_user.test | 83 +- sql/events.cc | 79 +- sql/sql_acl.cc | 124 +- sql/sql_lex.h | 25 - sql/sql_yacc.yy | 36 +- 13 files changed, 104 insertions(+), 2319 deletions(-) delete mode 100644 mysql-test/extra/rpl_tests/rpl_current_user.test diff --git a/mysql-test/extra/rpl_tests/rpl_current_user.test b/mysql-test/extra/rpl_tests/rpl_current_user.test deleted file mode 100644 index 7ec38e0c151..00000000000 --- a/mysql-test/extra/rpl_tests/rpl_current_user.test +++ /dev/null @@ -1,127 +0,0 @@ ---let $count=1 -connection master; - -if (`SELECT '$diff_table' = ''`) -{ - let $diff_table= mysql.user; -} - ---echo ---echo ---echo ---echo TEST STATEMENT: '$statement' ---echo -------------------------------------------------------------------------- - -if (`SELECT '$diff_columns' = ''`) -{ - eval CREATE VIEW test.bug48321_v1 AS SELECT user FROM $diff_table - WHERE user LIKE 'bug48321%'; -} - -if (`SELECT '$diff_columns' <> ''`) -{ - eval CREATE VIEW test.bug48321_v1 AS SELECT user, $diff_columns - FROM $diff_table WHERE user LIKE 'bug48321%'; -} - -while (`SELECT $count < 6`) -{ - --echo - --echo TEST STATEMENT: '$statement' - --echo CASE $count: - --echo ------- - - let $user2= 'bug48321_2'@'localhost'; - let $user3= 'bug48321_3'@'localhost'; - - let $user1= CURRENT_USER(); - if (`SELECT '$action'='RENAME'`) - { - let $user1= $user1 TO 'bug48321_4'@'localhost'; - let $user2= $user2 TO 'bug48321_5'@'localhost'; - let $user3= $user3 TO 'bug48321_6'@'localhost'; - } - - if (`SELECT '$action'='GRANT'`) - { - let $user1= $user1 IDENTIFIED BY 'user1'; - let $user3= $user3 IDENTIFIED BY ''; - } - - if (`SELECT $count=1`) - { - --echo # Only CURRENT_USER() in the user list of the test statement. - let $users_list= $user1; - } - - if (`SELECT $count=2`) - { - --echo # Two users are in the test statement, CURRENT_USER is the first one. - let $users_list= $user1, $user2; - } - - if (`SELECT $count=3`) - { - --echo # Two users are in the test statement, CURRENT_USER is the last one. - let $users_list= $user2, $user1; - } - - if (`SELECT $count=4`) - { - --echo # Three users are in the test statement, CURRENT_USER is the second one. - let $users_list= $user2, $user1, $user3; - } - - if (`SELECT $count=5`) - { - --echo # CURRENT_USER is not in the test statement. - let $users_list= $user2, $user3; - } - - --echo users_list= $users_list - --echo - --echo # Connect to master with user1, so user1 always is the current user, - --echo # when test statement is runing. - eval GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; - eval CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - - if (`SELECT '$action'='REVOKE'`) - { - --echo - --echo # Grant some privileges to users at first when testing - --echo # 'REVOKE ...' statement. - eval GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', - 'bug48321_3'@'localhost' WITH GRANT OPTION; - eval GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', - 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - } - - connect (conn1, 127.0.0.1, 'bug48321_1'@'localhost',,); - connection conn1; - --echo - let $temp= `SELECT "$statement"`; - eval $temp; - --echo - - disconnect conn1; - - connection master; - sync_slave_with_master; - - connection master; - let $diff_table_1= master:test.bug48321_v1; - let $diff_table_2= slave:test.bug48321_v1; - source include/diff_tables.inc; - --echo - - --echo # Delete all bug48321% users - connection master; - DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; - DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; - FLUSH PRIVILEGES; - - inc $count; -} -DROP VIEW test.bug48321_v1; diff --git a/mysql-test/suite/rpl/r/rpl_binlog_grant.result b/mysql-test/suite/rpl/r/rpl_binlog_grant.result index adf2175f3bb..4a789f361c6 100644 --- a/mysql-test/suite/rpl/r/rpl_binlog_grant.result +++ b/mysql-test/suite/rpl/r/rpl_binlog_grant.result @@ -17,15 +17,16 @@ show grants for x@y; Grants for x@y GRANT USAGE ON *.* TO 'x'@'y' GRANT SELECT ON `d1`.`t` TO 'x'@'y' -show binlog events from ; +show binlog events; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # drop database if exists d1 -master-bin.000001 # Query # # create database d1 -master-bin.000001 # Query # # use `d1`; create table t (s1 int) engine=innodb -master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `d1`; insert into t values (1) -master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Query # # use `d1`; grant select on t to 'x'@'y' +master-bin.000001 4 Format_desc 1 106 Server ver: VERSION, Binlog ver: 4 +master-bin.000001 106 Query 1 193 drop database if exists d1 +master-bin.000001 193 Query 1 272 create database d1 +master-bin.000001 272 Query 1 370 use `d1`; create table t (s1 int) engine=innodb +master-bin.000001 370 Query 1 436 BEGIN +master-bin.000001 436 Query 1 521 use `d1`; insert into t values (1) +master-bin.000001 521 Xid 1 548 COMMIT /* XID */ +master-bin.000001 548 Query 1 633 use `d1`; grant select on t to x@y start transaction; insert into t values (2); revoke select on t from x@y; @@ -37,18 +38,19 @@ s1 show grants for x@y; Grants for x@y GRANT USAGE ON *.* TO 'x'@'y' -show binlog events from ; +show binlog events; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Query # # drop database if exists d1 -master-bin.000001 # Query # # create database d1 -master-bin.000001 # Query # # use `d1`; create table t (s1 int) engine=innodb -master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `d1`; insert into t values (1) -master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Query # # use `d1`; grant select on t to 'x'@'y' -master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `d1`; insert into t values (2) -master-bin.000001 # Xid # # COMMIT /* XID */ -master-bin.000001 # Query # # use `d1`; revoke select on t from 'x'@'y' +master-bin.000001 4 Format_desc 1 106 Server ver: VERSION, Binlog ver: 4 +master-bin.000001 106 Query 1 193 drop database if exists d1 +master-bin.000001 193 Query 1 272 create database d1 +master-bin.000001 272 Query 1 370 use `d1`; create table t (s1 int) engine=innodb +master-bin.000001 370 Query 1 436 BEGIN +master-bin.000001 436 Query 1 521 use `d1`; insert into t values (1) +master-bin.000001 521 Xid 1 548 COMMIT /* XID */ +master-bin.000001 548 Query 1 633 use `d1`; grant select on t to x@y +master-bin.000001 633 Query 1 699 BEGIN +master-bin.000001 699 Query 1 784 use `d1`; insert into t values (2) +master-bin.000001 784 Xid 1 811 COMMIT /* XID */ +master-bin.000001 811 Query 1 899 use `d1`; revoke select on t from x@y drop user x@y; drop database d1; diff --git a/mysql-test/suite/rpl/r/rpl_events.result b/mysql-test/suite/rpl/r/rpl_events.result index 206ec52718c..b3fd85d7e28 100644 --- a/mysql-test/suite/rpl/r/rpl_events.result +++ b/mysql-test/suite/rpl/r/rpl_events.result @@ -251,45 +251,3 @@ DROP EVENT event44331_1; DROP EVENT event44331_2; DROP EVENT event44331_3; DROP EVENT event44331_4; -DROP VIEW IF EXISTS events_view; -DROP EVENT IF EXISTS event48321_1; -DROP EVENT IF EXISTS event48321_2; -DROP EVENT IF EXISTS event48321_3; -DROP EVENT IF EXISTS event48321_4; -CREATE VIEW events_view AS -SELECT EVENT_SCHEMA, EVENT_NAME, DEFINER FROM INFORMATION_SCHEMA.EVENTS -WHERE EVENT_NAME LIKE 'event48321%'; -CREATE DEFINER=CURRENT_USER() /*!50000 EVENT event48321_1 */ -ON SCHEDULE AT CURRENT_TIMESTAMP -ON COMPLETION PRESERVE DISABLE -DO SELECT 48321 as BUG; -CREATE DEFINER=CURRENT_USER() EVENT event48321_2 -ON SCHEDULE AT CURRENT_TIMESTAMP -ON COMPLETION PRESERVE DISABLE -DO SELECT 48321 as BUG; -CREATE /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3 -ON SCHEDULE AT CURRENT_TIMESTAMP -ON COMPLETION PRESERVE DISABLE -DO SELECT 48321 as BUG; -Comparing tables master:test.events_view and slave:test.events_view -ALTER DEFINER=CURRENT_USER() EVENT event48321_1 RENAME TO event48321_4; -ALTER DEFINER=CURRENT_USER() EVENT event48321_2 -ON SCHEDULE AT CURRENT_TIMESTAMP -ON COMPLETION PRESERVE DISABLE -DO SELECT 48321 as BUG; -ALTER /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3 -ON SCHEDULE AT CURRENT_TIMESTAMP -ON COMPLETION PRESERVE DISABLE -DO SELECT 48321 as BUG; -Comparing tables master:test.events_view and slave:test.events_view -ALTER /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3 -ON SCHEDULE AT CURRENT_TIMESTAMP -ON COMPLETION PRESERVE DISABLE -DO SELECT 48321 as BUG; ALTER EVENT event48321_2 ENABLE | -Comparing tables master:test.events_view and slave:test.events_view -ALTER EVENT event48321_3 ENABLE; -Comparing tables master:test.events_view and slave:test.events_view -DROP EVENT event48321_4; -DROP EVENT event48321_2; -DROP EVENT event48321_3; -DROP VIEW events_view; diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result index 74ebb3be948..fbfebbaa590 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result @@ -750,7 +750,7 @@ test_rpl e2 root@localhost SYSTEM RECURRING NULL 1 # # NULL ENABLED 1 latin1 lat USE test_rpl; SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation -test_rpl e2 root@localhost SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci +test_rpl e2 @ SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci ==========MASTER========== SELECT COUNT(*) FROM t1; COUNT(*) @@ -1079,7 +1079,7 @@ master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 'test1') master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # use `test_rpl`; CREATE DEFINER=`root`@`localhost` EVENT e1 ON SCHEDULE EVERY '1' SECOND COMMENT 'e_second_comment' DO DELETE FROM t1 -master-bin.000001 # Query 1 # use `test_rpl`; ALTER DEFINER=`root`@`localhost` EVENT e1 RENAME TO e2 +master-bin.000001 # Query 1 # use `test_rpl`; ALTER EVENT e1 RENAME TO e2 master-bin.000001 # Query 1 # use `test_rpl`; DROP EVENT e2 master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 diff --git a/mysql-test/suite/rpl/r/rpl_sp.result b/mysql-test/suite/rpl/r/rpl_sp.result index 02a5f33c843..7fedaf4c1ef 100644 --- a/mysql-test/suite/rpl/r/rpl_sp.result +++ b/mysql-test/suite/rpl/r/rpl_sp.result @@ -433,9 +433,9 @@ master-bin.000001 # Query 1 # use `mysqltest1`; create table t2 like t1 master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `foo3`() DETERMINISTIC insert into t1 values (15) -master-bin.000001 # Query 1 # use `mysqltest1`; grant CREATE ROUTINE, EXECUTE on mysqltest1.* to 'zedjzlcsjhd'@'127.0.0.1' -master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT on mysqltest1.t1 to 'zedjzlcsjhd'@'127.0.0.1' -master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT, INSERT on mysqltest1.t2 to 'zedjzlcsjhd'@'127.0.0.1' +master-bin.000001 # Query 1 # use `mysqltest1`; grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1 +master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1 +master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1 master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`zedjzlcsjhd`@`127.0.0.1` PROCEDURE `foo4`() DETERMINISTIC begin @@ -510,7 +510,7 @@ select * from t1 master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo master-bin.000001 # Query 1 # use `mysqltest1`; drop function fn1 master-bin.000001 # Query 1 # drop database mysqltest1 -master-bin.000001 # Query 1 # DROP USER 'zedjzlcsjhd'@'127.0.0.1' +master-bin.000001 # Query 1 # drop user "zedjzlcsjhd"@127.0.0.1 master-bin.000001 # Query 1 # use `test`; drop function if exists f1 master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11) READS SQL DATA @@ -675,13 +675,13 @@ CREATE DEFINER=`root`@`localhost` PROCEDURE `foo3`() insert into t1 values (15) /*!*/; SET TIMESTAMP=t/*!*/; -grant CREATE ROUTINE, EXECUTE on mysqltest1.* to 'zedjzlcsjhd'@'127.0.0.1' +grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1 /*!*/; SET TIMESTAMP=t/*!*/; -grant SELECT on mysqltest1.t1 to 'zedjzlcsjhd'@'127.0.0.1' +grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1 /*!*/; SET TIMESTAMP=t/*!*/; -grant SELECT, INSERT on mysqltest1.t2 to 'zedjzlcsjhd'@'127.0.0.1' +grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1 /*!*/; SET TIMESTAMP=t/*!*/; CREATE DEFINER=`zedjzlcsjhd`@`127.0.0.1` PROCEDURE `foo4`() @@ -842,7 +842,7 @@ SET TIMESTAMP=t/*!*/; drop database mysqltest1 /*!*/; SET TIMESTAMP=t/*!*/; -DROP USER 'zedjzlcsjhd'@'127.0.0.1' +drop user "zedjzlcsjhd"@127.0.0.1 /*!*/; use test/*!*/; SET TIMESTAMP=t/*!*/; diff --git a/mysql-test/suite/rpl/r/rpl_user.result b/mysql-test/suite/rpl/r/rpl_user.result index b1f1d73cf86..a98e7e9ca55 100644 --- a/mysql-test/suite/rpl/r/rpl_user.result +++ b/mysql-test/suite/rpl/r/rpl_user.result @@ -39,1754 +39,7 @@ show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; create user 'foo'@'fakehost' master-bin.000001 # Query # # use `test`; create user 'foo'@'fakehost', 'bar'@'fakehost' -master-bin.000001 # Query # # use `test`; RENAME USER 'foo'@'fakehost' TO 'foofoo'@'fakehost' -master-bin.000001 # Query # # use `test`; RENAME USER 'not_exist_user1'@'fakehost' TO 'foobar'@'fakehost', 'bar'@'fakehost' TO 'barbar'@'fakehost' -master-bin.000001 # Query # # use `test`; DROP USER 'foofoo'@'fakehost' -master-bin.000001 # Query # # use `test`; DROP USER 'not_exist_user1'@'fakehost', 'barbar'@'fakehost' - - - -TEST STATEMENT: 'RENAME USER $users_list' --------------------------------------------------------------------------- -CREATE VIEW test.bug48321_v1 AS SELECT user FROM mysql.user -WHERE user LIKE 'bug48321%'; - -TEST STATEMENT: 'RENAME USER $users_list' -CASE 1: -------- -# Only CURRENT_USER() in the user list of the test statement. -users_list= CURRENT_USER() TO 'bug48321_4'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -RENAME USER CURRENT_USER() TO 'bug48321_4'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'RENAME USER $users_list' -CASE 2: -------- -# Two users are in the test statement, CURRENT_USER is the first one. -users_list= CURRENT_USER() TO 'bug48321_4'@'localhost', 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -RENAME USER CURRENT_USER() TO 'bug48321_4'@'localhost', 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'RENAME USER $users_list' -CASE 3: -------- -# Two users are in the test statement, CURRENT_USER is the last one. -users_list= 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', CURRENT_USER() TO 'bug48321_4'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -RENAME USER 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', CURRENT_USER() TO 'bug48321_4'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'RENAME USER $users_list' -CASE 4: -------- -# Three users are in the test statement, CURRENT_USER is the second one. -users_list= 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', CURRENT_USER() TO 'bug48321_4'@'localhost', 'bug48321_3'@'localhost' TO 'bug48321_6'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -RENAME USER 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', CURRENT_USER() TO 'bug48321_4'@'localhost', 'bug48321_3'@'localhost' TO 'bug48321_6'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'RENAME USER $users_list' -CASE 5: -------- -# CURRENT_USER is not in the test statement. -users_list= 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', 'bug48321_3'@'localhost' TO 'bug48321_6'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -RENAME USER 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', 'bug48321_3'@'localhost' TO 'bug48321_6'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; -DROP VIEW test.bug48321_v1; - - - -TEST STATEMENT: 'DROP USER $users_list' --------------------------------------------------------------------------- -CREATE VIEW test.bug48321_v1 AS SELECT user FROM mysql.user -WHERE user LIKE 'bug48321%'; - -TEST STATEMENT: 'DROP USER $users_list' -CASE 1: -------- -# Only CURRENT_USER() in the user list of the test statement. -users_list= CURRENT_USER() - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -DROP USER CURRENT_USER(); - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'DROP USER $users_list' -CASE 2: -------- -# Two users are in the test statement, CURRENT_USER is the first one. -users_list= CURRENT_USER(), 'bug48321_2'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -DROP USER CURRENT_USER(), 'bug48321_2'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'DROP USER $users_list' -CASE 3: -------- -# Two users are in the test statement, CURRENT_USER is the last one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -DROP USER 'bug48321_2'@'localhost', CURRENT_USER(); - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'DROP USER $users_list' -CASE 4: -------- -# Three users are in the test statement, CURRENT_USER is the second one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -DROP USER 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'DROP USER $users_list' -CASE 5: -------- -# CURRENT_USER is not in the test statement. -users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -DROP USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; -DROP VIEW test.bug48321_v1; -DROP PROCEDURE IF EXISTS f1; -CREATE PROCEDURE p1() SELECT 1; - - - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list' --------------------------------------------------------------------------- -CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv -FROM mysql.user WHERE user LIKE 'bug48321%'; - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list' -CASE 1: -------- -# Only CURRENT_USER() in the user list of the test statement. -users_list= CURRENT_USER() - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(); - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list' -CASE 2: -------- -# Two users are in the test statement, CURRENT_USER is the first one. -users_list= CURRENT_USER(), 'bug48321_2'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(), 'bug48321_2'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list' -CASE 3: -------- -# Two users are in the test statement, CURRENT_USER is the last one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', CURRENT_USER(); - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list' -CASE 4: -------- -# Three users are in the test statement, CURRENT_USER is the second one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list' -CASE 5: -------- -# CURRENT_USER is not in the test statement. -users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; -DROP VIEW test.bug48321_v1; - - - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/' --------------------------------------------------------------------------- -CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv -FROM mysql.user WHERE user LIKE 'bug48321%'; - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/' -CASE 1: -------- -# Only CURRENT_USER() in the user list of the test statement. -users_list= CURRENT_USER() - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER() /*With comment*/; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/' -CASE 2: -------- -# Two users are in the test statement, CURRENT_USER is the first one. -users_list= CURRENT_USER(), 'bug48321_2'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(), 'bug48321_2'@'localhost' /*With comment*/; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/' -CASE 3: -------- -# Two users are in the test statement, CURRENT_USER is the last one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', CURRENT_USER() /*With comment*/; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/' -CASE 4: -------- -# Three users are in the test statement, CURRENT_USER is the second one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' /*With comment*/; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/' -CASE 5: -------- -# CURRENT_USER is not in the test statement. -users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' /*With comment*/; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; -DROP VIEW test.bug48321_v1; - - - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list' --------------------------------------------------------------------------- -CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv -FROM mysql.user WHERE user LIKE 'bug48321%'; - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list' -CASE 1: -------- -# Only CURRENT_USER() in the user list of the test statement. -users_list= CURRENT_USER() - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ CURRENT_USER(); - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list' -CASE 2: -------- -# Two users are in the test statement, CURRENT_USER is the first one. -users_list= CURRENT_USER(), 'bug48321_2'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ CURRENT_USER(), 'bug48321_2'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list' -CASE 3: -------- -# Two users are in the test statement, CURRENT_USER is the last one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ 'bug48321_2'@'localhost', CURRENT_USER(); - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list' -CASE 4: -------- -# Three users are in the test statement, CURRENT_USER is the second one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list' -CASE 5: -------- -# CURRENT_USER is not in the test statement. -users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; -DROP VIEW test.bug48321_v1; - - - -TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list' --------------------------------------------------------------------------- -CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv -FROM mysql.user WHERE user LIKE 'bug48321%'; - -TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list' -CASE 1: -------- -# Only CURRENT_USER() in the user list of the test statement. -users_list= CURRENT_USER() - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM CURRENT_USER(); - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list' -CASE 2: -------- -# Two users are in the test statement, CURRENT_USER is the first one. -users_list= CURRENT_USER(), 'bug48321_2'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM CURRENT_USER(), 'bug48321_2'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list' -CASE 3: -------- -# Two users are in the test statement, CURRENT_USER is the last one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM 'bug48321_2'@'localhost', CURRENT_USER(); - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list' -CASE 4: -------- -# Three users are in the test statement, CURRENT_USER is the second one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list' -CASE 5: -------- -# CURRENT_USER is not in the test statement. -users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; -DROP VIEW test.bug48321_v1; - - - -TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list' --------------------------------------------------------------------------- -CREATE VIEW test.bug48321_v1 AS SELECT user, Create_routine_priv -FROM mysql.user WHERE user LIKE 'bug48321%'; - -TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list' -CASE 1: -------- -# Only CURRENT_USER() in the user list of the test statement. -users_list= CURRENT_USER() - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE CREATE ROUTINE ON *.* FROM CURRENT_USER(); - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list' -CASE 2: -------- -# Two users are in the test statement, CURRENT_USER is the first one. -users_list= CURRENT_USER(), 'bug48321_2'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE CREATE ROUTINE ON *.* FROM CURRENT_USER(), 'bug48321_2'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list' -CASE 3: -------- -# Two users are in the test statement, CURRENT_USER is the last one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE CREATE ROUTINE ON *.* FROM 'bug48321_2'@'localhost', CURRENT_USER(); - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list' -CASE 4: -------- -# Three users are in the test statement, CURRENT_USER is the second one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE CREATE ROUTINE ON *.* FROM 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list' -CASE 5: -------- -# CURRENT_USER is not in the test statement. -users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE CREATE ROUTINE ON *.* FROM 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; -DROP VIEW test.bug48321_v1; - - - -TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list' --------------------------------------------------------------------------- -CREATE VIEW test.bug48321_v1 AS SELECT user, Routine_name, Proc_priv -FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; - -TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list' -CASE 1: -------- -# Only CURRENT_USER() in the user list of the test statement. -users_list= CURRENT_USER() - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER(); - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list' -CASE 2: -------- -# Two users are in the test statement, CURRENT_USER is the first one. -users_list= CURRENT_USER(), 'bug48321_2'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER(), 'bug48321_2'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list' -CASE 3: -------- -# Two users are in the test statement, CURRENT_USER is the last one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM 'bug48321_2'@'localhost', CURRENT_USER(); - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list' -CASE 4: -------- -# Three users are in the test statement, CURRENT_USER is the second one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list' -CASE 5: -------- -# CURRENT_USER is not in the test statement. -users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -# Grant some privileges to users at first when testing -# 'REVOKE ...' statement. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', -'bug48321_3'@'localhost' WITH GRANT OPTION; -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', -'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; -DROP VIEW test.bug48321_v1; - - - -TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION' --------------------------------------------------------------------------- -CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv, Password -FROM mysql.user WHERE user LIKE 'bug48321%'; - -TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION' -CASE 1: -------- -# Only CURRENT_USER() in the user list of the test statement. -users_list= CURRENT_USER() IDENTIFIED BY 'user1' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1' WITH GRANT OPTION; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION' -CASE 2: -------- -# Two users are in the test statement, CURRENT_USER is the first one. -users_list= CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost' WITH GRANT OPTION; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION' -CASE 3: -------- -# Two users are in the test statement, CURRENT_USER is the last one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1' WITH GRANT OPTION; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION' -CASE 4: -------- -# Three users are in the test statement, CURRENT_USER is the second one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '' WITH GRANT OPTION; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION' -CASE 5: -------- -# CURRENT_USER is not in the test statement. -users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '' WITH GRANT OPTION; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; -DROP VIEW test.bug48321_v1; - - - -TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION' --------------------------------------------------------------------------- -CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv, Password -FROM mysql.user WHERE user LIKE 'bug48321%'; - -TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION' -CASE 1: -------- -# Only CURRENT_USER() in the user list of the test statement. -users_list= CURRENT_USER() IDENTIFIED BY 'user1' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1' /* With Comment */ WITH GRANT OPTION; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION' -CASE 2: -------- -# Two users are in the test statement, CURRENT_USER is the first one. -users_list= CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost' /* With Comment */ WITH GRANT OPTION; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION' -CASE 3: -------- -# Two users are in the test statement, CURRENT_USER is the last one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1' /* With Comment */ WITH GRANT OPTION; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION' -CASE 4: -------- -# Three users are in the test statement, CURRENT_USER is the second one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '' /* With Comment */ WITH GRANT OPTION; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION' -CASE 5: -------- -# CURRENT_USER is not in the test statement. -users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '' /* With Comment */ WITH GRANT OPTION; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; -DROP VIEW test.bug48321_v1; - - - -TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list' --------------------------------------------------------------------------- -CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Password -FROM mysql.user WHERE user LIKE 'bug48321%'; - -TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list' -CASE 1: -------- -# Only CURRENT_USER() in the user list of the test statement. -users_list= CURRENT_USER() IDENTIFIED BY 'user1' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO CURRENT_USER() IDENTIFIED BY 'user1'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list' -CASE 2: -------- -# Two users are in the test statement, CURRENT_USER is the first one. -users_list= CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list' -CASE 3: -------- -# Two users are in the test statement, CURRENT_USER is the last one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list' -CASE 4: -------- -# Three users are in the test statement, CURRENT_USER is the second one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY ''; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list' -CASE 5: -------- -# CURRENT_USER is not in the test statement. -users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY ''; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; -DROP VIEW test.bug48321_v1; - - - -TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list' --------------------------------------------------------------------------- -CREATE VIEW test.bug48321_v1 AS SELECT user, Create_routine_priv -FROM mysql.user WHERE user LIKE 'bug48321%'; - -TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list' -CASE 1: -------- -# Only CURRENT_USER() in the user list of the test statement. -users_list= CURRENT_USER() IDENTIFIED BY 'user1' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT CREATE ROUTINE ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list' -CASE 2: -------- -# Two users are in the test statement, CURRENT_USER is the first one. -users_list= CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT CREATE ROUTINE ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list' -CASE 3: -------- -# Two users are in the test statement, CURRENT_USER is the last one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT CREATE ROUTINE ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list' -CASE 4: -------- -# Three users are in the test statement, CURRENT_USER is the second one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT CREATE ROUTINE ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY ''; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list' -CASE 5: -------- -# CURRENT_USER is not in the test statement. -users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT CREATE ROUTINE ON *.* TO 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY ''; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; -DROP VIEW test.bug48321_v1; -DROP PROCEDURE p1; - - - -TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list' --------------------------------------------------------------------------- -CREATE VIEW test.bug48321_v1 AS SELECT user, Routine_name, Proc_priv -FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; - -TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list' -CASE 1: -------- -# Only CURRENT_USER() in the user list of the test statement. -users_list= CURRENT_USER() IDENTIFIED BY 'user1' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER() IDENTIFIED BY 'user1'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list' -CASE 2: -------- -# Two users are in the test statement, CURRENT_USER is the first one. -users_list= CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list' -CASE 3: -------- -# Two users are in the test statement, CURRENT_USER is the last one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1'; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list' -CASE 4: -------- -# Three users are in the test statement, CURRENT_USER is the second one. -users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY ''; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; - -TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list' -CASE 5: -------- -# CURRENT_USER is not in the test statement. -users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '' - -# Connect to master with user1, so user1 always is the current user, -# when test statement is runing. -GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' - WITH GRANT OPTION; -CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' - IDENTIFIED BY 'user3'; - -GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY ''; - -Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 - -# Delete all bug48321% users -DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; -DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; -FLUSH PRIVILEGES; -DROP VIEW test.bug48321_v1; +master-bin.000001 # Query # # use `test`; rename user 'foo'@'fakehost' to 'foofoo'@'fakehost' +master-bin.000001 # Query # # use `test`; rename user 'not_exist_user1'@'fakehost' to 'foobar'@'fakehost', 'bar'@'fakehost' to 'barbar'@'fakehost' +master-bin.000001 # Query # # use `test`; drop user 'foofoo'@'fakehost' +master-bin.000001 # Query # # use `test`; drop user 'not_exist_user1'@'fakehost', 'barbar'@'fakehost' diff --git a/mysql-test/suite/rpl/t/rpl_binlog_grant.test b/mysql-test/suite/rpl/t/rpl_binlog_grant.test index 64f4e8b2eeb..31163927ce2 100644 --- a/mysql-test/suite/rpl/t/rpl_binlog_grant.test +++ b/mysql-test/suite/rpl/t/rpl_binlog_grant.test @@ -25,7 +25,9 @@ grant select on t to x@y; # rollback; show grants for x@y; ---source include/show_binlog_events.inc +--replace_result $VERSION VERSION +--replace_regex /\/\* xid=.* \*\//\/* XID *\// +show binlog events; start transaction; insert into t values (2); revoke select on t from x@y; @@ -35,7 +37,9 @@ revoke select on t from x@y; commit; select * from t; show grants for x@y; ---source include/show_binlog_events.inc +--replace_result $VERSION VERSION +--replace_regex /\/\* xid=.* \*\//\/* XID *\// +show binlog events; drop user x@y; drop database d1; --sync_slave_with_master diff --git a/mysql-test/suite/rpl/t/rpl_events.test b/mysql-test/suite/rpl/t/rpl_events.test index 25976f779e3..7720ad6658c 100644 --- a/mysql-test/suite/rpl/t/rpl_events.test +++ b/mysql-test/suite/rpl/t/rpl_events.test @@ -105,85 +105,3 @@ DROP EVENT event44331_2; DROP EVENT event44331_3; DROP EVENT event44331_4; sync_slave_with_master; - -# -# BUG#48321 -# This test verifies if the definer is consistent between master and slave, -# when the event is created or altered with the DEFINER clause that the -# DEFINER is set to CURRENT_USER() -# -connection master; ---disable_warnings -DROP VIEW IF EXISTS events_view; -DROP EVENT IF EXISTS event48321_1; -DROP EVENT IF EXISTS event48321_2; -DROP EVENT IF EXISTS event48321_3; -DROP EVENT IF EXISTS event48321_4; ---enable_warnings - -CREATE VIEW events_view AS - SELECT EVENT_SCHEMA, EVENT_NAME, DEFINER FROM INFORMATION_SCHEMA.EVENTS - WHERE EVENT_NAME LIKE 'event48321%'; -let $diff_table_1= master:test.events_view; -let $diff_table_2= slave:test.events_view; - -CREATE DEFINER=CURRENT_USER() /*!50000 EVENT event48321_1 */ - ON SCHEDULE AT CURRENT_TIMESTAMP - ON COMPLETION PRESERVE DISABLE - DO SELECT 48321 as BUG; - -CREATE DEFINER=CURRENT_USER() EVENT event48321_2 - ON SCHEDULE AT CURRENT_TIMESTAMP - ON COMPLETION PRESERVE DISABLE - DO SELECT 48321 as BUG; - -CREATE /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3 - ON SCHEDULE AT CURRENT_TIMESTAMP - ON COMPLETION PRESERVE DISABLE - DO SELECT 48321 as BUG; -sync_slave_with_master; - ---source include/diff_tables.inc - -connection master; -ALTER DEFINER=CURRENT_USER() EVENT event48321_1 RENAME TO event48321_4; - -ALTER DEFINER=CURRENT_USER() EVENT event48321_2 - ON SCHEDULE AT CURRENT_TIMESTAMP - ON COMPLETION PRESERVE DISABLE - DO SELECT 48321 as BUG; - -ALTER /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3 - ON SCHEDULE AT CURRENT_TIMESTAMP - ON COMPLETION PRESERVE DISABLE - DO SELECT 48321 as BUG; -sync_slave_with_master; - ---source include/diff_tables.inc - -# Two statements in on query -connection master; -DELIMITER |; -ALTER /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3 - ON SCHEDULE AT CURRENT_TIMESTAMP - ON COMPLETION PRESERVE DISABLE - DO SELECT 48321 as BUG; ALTER EVENT event48321_2 ENABLE | -DELIMITER ;| -sync_slave_with_master; - ---source include/diff_tables.inc - -#No Event boday -connection master; -ALTER EVENT event48321_3 ENABLE; -sync_slave_with_master; - ---source include/diff_tables.inc - -connection master; -DROP EVENT event48321_4; -DROP EVENT event48321_2; -DROP EVENT event48321_3; -DROP VIEW events_view; ---source include/master-slave-end.inc - diff --git a/mysql-test/suite/rpl/t/rpl_user.test b/mysql-test/suite/rpl/t/rpl_user.test index 2adb822839a..b8fe41d03c4 100644 --- a/mysql-test/suite/rpl/t/rpl_user.test +++ b/mysql-test/suite/rpl/t/rpl_user.test @@ -54,85 +54,8 @@ drop user 'not_exist_user1'@'fakehost', 'not_exist_user2'@'fakehost'; sync_slave_with_master; select Host,User from mysql.user where Host='fakehost'; +# +# show the binlog events on the master +# connection master; source include/show_binlog_events.inc; - -# -# BUG#48321 -# -let $action= RENAME; -let $statement= RENAME USER \$users_list; -source extra/rpl_tests/rpl_current_user.test; - -let $action= DROP; -let $statement= DROP USER \$users_list; -source extra/rpl_tests/rpl_current_user.test; - ---disable_warnings -DROP PROCEDURE IF EXISTS f1; ---enable_warnings -CREATE PROCEDURE p1() SELECT 1; -#REVOKE ALL PRIVILEGES -let $action= REVOKE; -let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv; -let $statement= REVOKE ALL PRIVILEGES, GRANT OPTION FROM \$users_list; -source extra/rpl_tests/rpl_current_user.test; - -#REVOKE ALL PRIVILEGES with comment -let $action= REVOKE; -let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv; -let $statement= REVOKE ALL PRIVILEGES, GRANT OPTION FROM \$users_list /*With comment*/; -source extra/rpl_tests/rpl_current_user.test; - -#REVOKE ALL PRIVILEGES with comment -let $action= REVOKE; -let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv; -let $statement= REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ \$users_list; -source extra/rpl_tests/rpl_current_user.test; - -let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv; -#REVOKE ON TABLE -let $statement= REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM \$users_list; -source extra/rpl_tests/rpl_current_user.test; - -#REVOKE ON CREATE ROUTINE -let $diff_columns= Create_routine_priv; -let $statement= REVOKE CREATE ROUTINE ON *.* FROM \$users_list; -source extra/rpl_tests/rpl_current_user.test; - -#REVOKE ON ROUTINE -let $diff_table= mysql.procs_priv; -let $diff_columns= Routine_name, Proc_priv; -let $statement= REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM \$users_list; -source extra/rpl_tests/rpl_current_user.test; - -let $diff_table= mysql.user; -#GRANT ALL PRIVILEGES -let $action= GRANT; -let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv, Password; -let $statement= GRANT ALL PRIVILEGES ON *.* TO \$users_list WITH GRANT OPTION; -source extra/rpl_tests/rpl_current_user.test; - -#GRANT ALL PRIVILEGES with comment -let $action= GRANT; -let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv, Password; -let $statement= GRANT ALL PRIVILEGES ON *.* TO \$users_list /* With Comment */ WITH GRANT OPTION; -source extra/rpl_tests/rpl_current_user.test; - -#GRANT ON TABLE -let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Password; -let $statement= GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO \$users_list; -source extra/rpl_tests/rpl_current_user.test; - -#GRANT ON CREATE ROUTINE -let $diff_columns= Create_routine_priv; -let $statement= GRANT CREATE ROUTINE ON *.* TO \$users_list; -source extra/rpl_tests/rpl_current_user.test; - -#GRANT ON ROUTINE -let $diff_table= mysql.procs_priv; -let $diff_columns= Routine_name, Proc_priv; -let $statement= GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO \$users_list; - -DROP PROCEDURE p1; -source extra/rpl_tests/rpl_current_user.test; diff --git a/sql/events.cc b/sql/events.cc index 6c8bdb1ea0f..4c6dd0f35d1 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -341,48 +341,31 @@ common_1_lev_code: } -/* - Binlog '{CREATE|ALTER} EVENT' statements. - Definer part is always rewritten, for definer can be CURRENT_USER() function. - +/** + Create a new query string for removing executable comments + for avoiding leak and keeping consistency of the execution + on master and slave. + @param[in] thd Thread handler - @param[in] create CREATE or ALTER statement + @param[in] buf Query string @return - FASE ok - TRUE error + 0 ok + 1 error */ -static bool event_write_bin_log(THD *thd, bool create) +static int +create_query_string(THD *thd, String *buf) { - String log_query; - if (create) - { - /* Append the "CREATE" part of the query */ - if (log_query.append(STRING_WITH_LEN("CREATE "))) - return TRUE; - } - else - { - /* Append the "ALETR " part of the query */ - if (log_query.append(STRING_WITH_LEN("ALTER "))) - return TRUE; - } - - /* Append definer - If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER - will be written into the binary log as the definer for the SQL thread. - */ - append_definer(thd, &log_query, &(thd->lex->definer->user), - &(thd->lex->definer->host)); - + /* Append the "CREATE" part of the query */ + if (buf->append(STRING_WITH_LEN("CREATE "))) + return 1; + /* Append definer */ + append_definer(thd, buf, &(thd->lex->definer->user), &(thd->lex->definer->host)); /* Append the left part of thd->query after "DEFINER" part */ - if (log_query.append(thd->lex->stmt_definition_begin, - thd->lex->stmt_definition_end - - thd->lex->stmt_definition_begin)) - return TRUE; - - return write_bin_log(thd, TRUE, log_query.c_ptr_safe(), log_query.length()) - != 0; + if (buf->append(thd->lex->stmt_definition_begin)) + return 1; + + return 0; } /** @@ -397,7 +380,8 @@ static bool event_write_bin_log(THD *thd, bool create) @sa Events::drop_event for the notes about locking, pre-locking and Events DDL. - @retval FALSE OK @retval TRUE Error (reported) + @retval FALSE OK + @retval TRUE Error (reported) */ bool @@ -481,7 +465,22 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, binlog the create event unless it's been successfully dropped */ if (!dropped) - ret= event_write_bin_log(thd, TRUE); + { + /* Binlog the create event. */ + DBUG_ASSERT(thd->query() && thd->query_length()); + String log_query; + if (create_query_string(thd, &log_query)) + { + sql_print_error("Event Error: An error occurred while creating query string, " + "before writing it into binary log."); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; + DBUG_RETURN(TRUE); + } + /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER + will be written into the binary log as the definer for the SQL thread. */ + ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length()); + } } pthread_mutex_unlock(&LOCK_event_metadata); /* Restore the state of binlog format */ @@ -603,7 +602,9 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, if (event_queue) event_queue->update_event(thd, parse_data->dbname, parse_data->name, new_element); - ret= event_write_bin_log(thd, FALSE); + /* Binlog the alter event. */ + DBUG_ASSERT(thd->query() && thd->query_length()); + ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } } pthread_mutex_unlock(&LOCK_event_metadata); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 70983f69746..a8828d15cae 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -194,7 +194,6 @@ static bool compare_hostname(const acl_host_and_ip *host,const char *hostname, const char *ip); static my_bool acl_load(THD *thd, TABLE_LIST *tables); static my_bool grant_load(THD *thd, TABLE_LIST *tables); -static bool acl_write_bin_log(THD *thd, List &list, bool clear_error); /* Convert scrambled password to binary form, according to scramble type, @@ -3226,8 +3225,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, if (!result) /* success */ { - if (acl_write_bin_log(thd, user_list, TRUE)) - result= -1; + result= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } rw_unlock(&LOCK_grant); @@ -3403,7 +3401,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, if (write_to_binlog) { - result|= acl_write_bin_log(thd, user_list, FALSE); + if (write_bin_log(thd, FALSE, thd->query(), thd->query_length())) + result= TRUE; } rw_unlock(&LOCK_grant); @@ -3532,7 +3531,7 @@ bool mysql_grant(THD *thd, const char *db, List &list, if (!result) { - result= acl_write_bin_log(thd, list, TRUE); + result= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } rw_unlock(&LOCK_grant); @@ -5664,9 +5663,9 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop, } -static void append_user(String *str, LEX_USER *user, bool comma= TRUE) +static void append_user(String *str, LEX_USER *user) { - if (comma && str->length()) + if (str->length()) str->append(','); str->append('\''); str->append(user->user.str); @@ -5675,65 +5674,6 @@ static void append_user(String *str, LEX_USER *user, bool comma= TRUE) str->append('\''); } -/* - The operations(DROP, RENAME, REVOKE, GRANT) will cause inconsistency between - master and slave, when CURRENT_USER() is used. To solve this problem, we - construct a new binlog statement in which CURRENT_USER() is replaced by - the real user name and host name. - */ -static bool acl_write_bin_log(THD *thd, List &list, bool clear_error) -{ - String log_query; - LEX *lex= thd->lex; - List_iterator user_list(list); - LEX_USER *user, *tmp_user; - - if (!mysql_bin_log.is_open()) - return FALSE; - - if (log_query.append(lex->stmt_begin, lex->stmt_user_begin - lex->stmt_begin)) - return TRUE; - while ((tmp_user= user_list++)) - { - if (!(user= get_current_user(thd, tmp_user))) - continue; - - /* - No User, but a password? - They did GRANT ... TO CURRENT_USER() IDENTIFIED BY ... ! - Get the current user, and shallow-copy the new password to them! - */ - if (!tmp_user->user.str && tmp_user->password.str) - user->password= tmp_user->password; - - if (log_query.append(" ", 1)) - return TRUE; - append_user(&log_query, user, FALSE); - /* Only 'GRANT' have password */ - if (user->password.str) - { - if (log_query.append(STRING_WITH_LEN(" IDENTIFIED BY ")) || - log_query.append(STRING_WITH_LEN("PASSWORD ")) || - log_query.append("'", 1) || - log_query.append(user->password.str, - user->password.length) || - log_query.append("'", 1)) - return TRUE; - } - if (log_query.append(",", 1)) - return TRUE; - } - /* It is binlogged only when at least one user is in the query */ - if (log_query.c_ptr()[log_query.length()-1] == ',') - { - log_query.length(log_query.length()-1); - if (log_query.append(lex->stmt_user_end, lex->stmt_end - lex->stmt_user_end)) - return TRUE; - return write_bin_log(thd, clear_error, log_query.c_ptr_safe(), - log_query.length()) != 0; - } - return FALSE; -} /* Create a list of users. @@ -5840,7 +5780,6 @@ bool mysql_drop_user(THD *thd, List &list) { int result; String wrong_users; - String log_query; LEX_USER *user_name, *tmp_user_name; List_iterator user_list(list); TABLE_LIST tables[GRANT_TABLES]; @@ -5870,7 +5809,6 @@ bool mysql_drop_user(THD *thd, List &list) rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); - log_query.append(STRING_WITH_LEN("DROP USER")); while ((tmp_user_name= user_list++)) { if (!(user_name= get_current_user(thd, tmp_user_name))) @@ -5878,17 +5816,6 @@ bool mysql_drop_user(THD *thd, List &list) result= TRUE; continue; } - - /* - The operation will cause inconsistency between master and slave, when - CURRENT_USER() is used. To solve this problem, we construct a new - binlog statement in which CURRENT_USER() is replaced by the real user - name and host name. - */ - log_query.append(STRING_WITH_LEN(" ")); - append_user(&log_query, user_name, FALSE); - log_query.append(STRING_WITH_LEN(",")); - if (handle_grant_data(tables, 1, user_name, NULL) <= 0) { append_user(&wrong_users, user_name); @@ -5907,13 +5834,7 @@ bool mysql_drop_user(THD *thd, List &list) my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe()); if (some_users_deleted) - { - if (log_query.c_ptr()[log_query.length()-1] == ',') - { - log_query.length(log_query.length()-1); - result|= write_bin_log(thd, FALSE, log_query.c_ptr_safe(), log_query.length()); - } - } + result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length()); rw_unlock(&LOCK_grant); close_thread_tables(thd); @@ -5941,7 +5862,6 @@ bool mysql_rename_user(THD *thd, List &list) { int result; String wrong_users; - String log_query; LEX_USER *user_from, *tmp_user_from; LEX_USER *user_to, *tmp_user_to; List_iterator user_list(list); @@ -5969,7 +5889,6 @@ bool mysql_rename_user(THD *thd, List &list) rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); - log_query.append(STRING_WITH_LEN("RENAME USER")); while ((tmp_user_from= user_list++)) { if (!(user_from= get_current_user(thd, tmp_user_from))) @@ -5985,18 +5904,6 @@ bool mysql_rename_user(THD *thd, List &list) } DBUG_ASSERT(user_to != 0); /* Syntax enforces pairs of users. */ - /* - The operation will cause inconsistency between master and slave, when - CURRENT_USER() is used. To solve this problem, we construct a new - binlog statement in which CURRENT_USER() is replaced by the real user - name and host name. - */ - log_query.append(STRING_WITH_LEN(" ")); - append_user(&log_query, user_from, FALSE); - log_query.append(STRING_WITH_LEN(" TO ")); - append_user(&log_query, user_to, FALSE); - log_query.append(STRING_WITH_LEN(",")); - /* Search all in-memory structures and grant tables for a mention of the new user name. @@ -6018,15 +5925,9 @@ bool mysql_rename_user(THD *thd, List &list) if (result) my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe()); - - if (some_users_renamed) - { - if (log_query.c_ptr()[log_query.length()-1] == ',') - { - log_query.length(log_query.length()-1); - result|= write_bin_log(thd, FALSE, log_query.c_ptr_safe(), log_query.length()); - } - } + + if (some_users_renamed && mysql_bin_log.is_open()) + result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length()); rw_unlock(&LOCK_grant); close_thread_tables(thd); @@ -6216,9 +6117,8 @@ bool mysql_revoke_all(THD *thd, List &list) VOID(pthread_mutex_unlock(&acl_cache->lock)); - int binlog_error= 0; - if (acl_write_bin_log(thd, list, FALSE)) - binlog_error= 1; + int binlog_error= + write_bin_log(thd, FALSE, thd->query(), thd->query_length()); rw_unlock(&LOCK_grant); close_thread_tables(thd); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 99f5257eb5e..4e4794ef2cf 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1727,8 +1727,6 @@ typedef struct st_lex : public Query_tables_list - CREATE TRIGGER (points to "TRIGGER"); - CREATE PROCEDURE (points to "PROCEDURE"); - CREATE FUNCTION (points to "FUNCTION" or "AGGREGATE"); - - CREATE VIEW(points to "VIEW"); - - CREATE EVENT(points to "EVENT"); This pointer is required to add possibly omitted DEFINER-clause to the DDL-statement before dumping it to the binlog. @@ -1737,29 +1735,6 @@ typedef struct st_lex : public Query_tables_list const char *stmt_definition_end; - /* - stmt_begin is intended to point to the begin of every statement. - It is now used in the following statements: - - GRANT ALL PRIVELEGES ON *.* (points to "GRANT"); - - REVOKE ALL PRIVELEGES ON *.* (points to "REVOKE"); - */ - const char *stmt_begin; - const char *stmt_end; - - /* - stmt_user_begin is intended to point to the begin of the user list in - the following statements: - - GRANT ALL PRIVELEGES ON *.* TO 'username'@'hostname' - (points to "'username'"); - - REVOKE ALL PRIVELEGES ON *.* FROM 'username'@'hostname' - (points to "'username'"); - - these pointers are required to replace the CURRENT_USER() - function by the real user before dumping it to the binlog. - */ - const char *stmt_user_begin; - const char *stmt_user_end; - /** During name resolution search only in the table list given by Name_resolution_context::first_name_resolution_table and diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 92c4de5b462..8dc08f8425f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1562,11 +1562,7 @@ opt_end_of_input: ; verb_clause: - remember_name statement remember_end - { - Lex->stmt_begin= $1; - Lex->stmt_end= $3; - } + statement | begin ; @@ -5747,7 +5743,7 @@ alter: } view_tail {} - | ALTER definer_opt remember_name EVENT_SYM sp_name + | ALTER definer_opt EVENT_SYM sp_name { /* It is safe to use Lex->spname because @@ -5759,8 +5755,7 @@ alter: if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD))) MYSQL_YYABORT; - Lex->event_parse_data->identifier= $5; - Lex->stmt_definition_begin= $3; + Lex->event_parse_data->identifier= $4; Lex->sql_command= SQLCOM_ALTER_EVENT; } @@ -5770,7 +5765,7 @@ alter: opt_ev_comment opt_ev_sql_stmt { - if (!($7 || $8 || $9 || $10 || $11)) + if (!($6 || $7 || $8 || $9 || $10)) { my_parse_error(ER(ER_SYNTAX_ERROR)); MYSQL_YYABORT; @@ -5831,16 +5826,7 @@ opt_ev_rename_to: ; opt_ev_sql_stmt: - /* empty*/ - { - $$= 0; - /* - Lex->sp_head is not initialized when event body is empty. - So we can not use Lex->sp_head->set_stmt_end() to set - stmt_definition_end. - */ - Lex->stmt_definition_end= (char*) YYLIP->get_cpp_tok_end(); - } + /* empty*/ { $$= 0;} | DO_SYM ev_sql_stmt { $$= 1; } ; @@ -11530,7 +11516,6 @@ user: $$->user = $1; $$->host.str= (char *) "%"; $$->host.length= 1; - Lex->stmt_user_end= YYLIP->get_cpp_ptr(); if (check_string_char_length(&$$->user, ER(ER_USERNAME), USERNAME_CHAR_LENGTH, @@ -11543,7 +11528,6 @@ user: if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user)))) MYSQL_YYABORT; $$->user = $1; $$->host=$3; - Lex->stmt_user_end= YYLIP->get_cpp_ptr(); if (check_string_char_length(&$$->user, ER(ER_USERNAME), USERNAME_CHAR_LENGTH, @@ -11553,7 +11537,6 @@ user: } | CURRENT_USER optional_braces { - Lex->stmt_user_end= YYLIP->get_cpp_ptr(); if (!($$=(LEX_USER*) YYTHD->alloc(sizeof(st_lex_user)))) MYSQL_YYABORT; /* @@ -12744,10 +12727,9 @@ user_list: ; grant_list: - { Lex->stmt_user_begin= YYLIP->get_cpp_ptr(); } grant_user { - if (Lex->users_list.push_back($2)) + if (Lex->users_list.push_back($1)) MYSQL_YYABORT; } | grant_list ',' grant_user @@ -12760,7 +12742,6 @@ grant_list: grant_user: user IDENTIFIED_SYM BY TEXT_STRING { - Lex->stmt_user_end= YYLIP->get_cpp_ptr(); $$=$1; $1->password=$4; if ($4.length) { @@ -12787,10 +12768,7 @@ grant_user: } } | user IDENTIFIED_SYM BY PASSWORD TEXT_STRING - { - Lex->stmt_user_end= YYLIP->get_cpp_ptr(); - $$= $1; $1->password= $5; - } + { $$= $1; $1->password= $5; } | user { $$= $1; $1->password= null_lex_str; } ; From 090c75d2b0e202ca103215fbf1211d7a85defae5 Mon Sep 17 00:00:00 2001 From: Magne Mahre Date: Tue, 2 Feb 2010 16:34:32 +0100 Subject: [PATCH 119/157] Cleanup fix for WL#5154 that splits commands handling for --default-character-set and --character-set-server such that only the first will give a deprecation warning. Apart from that, the two options should do the same. --- sql/mysqld.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 40026867aaf..ca20299b36e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5733,7 +5733,8 @@ enum options_mysqld OPT_GENERAL_LOG_FILE, OPT_SLOW_QUERY_LOG_FILE, OPT_IGNORE_BUILTIN_INNODB, - OPT_BINLOG_DIRECT_NON_TRANS_UPDATE + OPT_BINLOG_DIRECT_NON_TRANS_UPDATE, + OPT_DEFAULT_CHARACTER_SET_OLD }; @@ -5859,7 +5860,8 @@ struct my_option my_long_options[] = {"debug", '#', "Debug log.", (uchar**) &default_dbug_option, (uchar**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"default-character-set", 'C', "Set the default character set (deprecated option, use --character-set-server instead).", + {"default-character-set", OPT_DEFAULT_CHARACTER_SET_OLD, + "Set the default character set (deprecated option, use --character-set-server instead).", (uchar**) &default_character_set_name, (uchar**) &default_character_set_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, {"default-collation", OPT_DEFAULT_COLLATION_OLD, "Set the default collation (deprecated option, use --collation-server instead).", @@ -7921,8 +7923,12 @@ mysqld_get_one_option(int optid, case 'b': strmake(mysql_home,argument,sizeof(mysql_home)-1); break; + case OPT_DEFAULT_CHARACTER_SET_OLD: // --default-character-set + WARN_DEPRECATED(NULL, VER_CELOSIA, + "--default-character-set", + "--character-set-server"); + /* Fall through */ case 'C': - WARN_DEPRECATED(NULL, VER_CELOSIA, "--default-character-set", "--character-set-server"); if (default_collation_name == compiled_default_collation_name) default_collation_name= 0; break; From e4b7138561d567041dbb2aa8ed366e3c3d31d58b Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 2 Feb 2010 18:37:56 +0200 Subject: [PATCH 120/157] Bug #49445: Assertion failed: 0, file .\item_row.cc, line 55 with fulltext search and row op. The search for fulltext indexes is searching for some special predicate layouts. While doing so it's not checking for the number of columns of the expressions it tries to calculate. And since row expressions can't return a single scalar value there was a crash. Fixed by checking if the expressions are scalar (in addition to being constant) before calling Item::val_xxx() methods. --- mysql-test/r/fulltext.result | 8 ++++++++ mysql-test/t/fulltext.test | 10 ++++++++++ sql/sql_select.cc | 24 ++++++++++++------------ 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 1ef6656e7a4..f65823518d4 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -603,4 +603,12 @@ WHERE t3.a=t1.a AND MATCH(b2) AGAINST('scargill' IN BOOLEAN MODE) count(*) 0 DROP TABLE t1,t2,t3; +# +# Bug #49445: Assertion failed: 0, file .\item_row.cc, line 55 with +# fulltext search and row op +# +CREATE TABLE t1(a CHAR(1),FULLTEXT(a)); +SELECT 1 FROM t1 WHERE MATCH(a) AGAINST ('') AND ROW(a,a) > ROW(1,1); +1 +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 3853a224fd5..57a90483ea9 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -545,4 +545,14 @@ SELECT count(*) FROM t1 WHERE DROP TABLE t1,t2,t3; +--echo # +--echo # Bug #49445: Assertion failed: 0, file .\item_row.cc, line 55 with +--echo # fulltext search and row op +--echo # + +CREATE TABLE t1(a CHAR(1),FULLTEXT(a)); +SELECT 1 FROM t1 WHERE MATCH(a) AGAINST ('') AND ROW(a,a) > ROW(1,1); +DROP TABLE t1; + + --echo End of 5.1 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0e36d35289f..da85ca27339 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3650,20 +3650,20 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array, cond_func=(Item_func_match *)cond; else if (func->arg_count == 2) { - Item_func *arg0=(Item_func *)(func->arguments()[0]), - *arg1=(Item_func *)(func->arguments()[1]); - if (arg1->const_item() && + Item *arg0= func->arguments()[0], + *arg1= func->arguments()[1]; + if (arg1->const_item() && arg1->cols() == 1 && ((functype == Item_func::GE_FUNC && arg1->val_real() > 0) || - (functype == Item_func::GT_FUNC && arg1->val_real() >=0)) && - arg0->type() == Item::FUNC_ITEM && - arg0->functype() == Item_func::FT_FUNC) - cond_func=(Item_func_match *) arg0; - else if (arg0->const_item() && + (functype == Item_func::GT_FUNC && arg1->val_real() >= 0)) && + arg0->type() == Item::FUNC_ITEM && + ((Item_func *) arg0)->functype() == Item_func::FT_FUNC) + cond_func= (Item_func_match *) arg0; + else if (arg0->const_item() && arg0->cols() == 1 && ((functype == Item_func::LE_FUNC && arg0->val_real() > 0) || - (functype == Item_func::LT_FUNC && arg0->val_real() >=0)) && - arg1->type() == Item::FUNC_ITEM && - arg1->functype() == Item_func::FT_FUNC) - cond_func=(Item_func_match *) arg1; + (functype == Item_func::LT_FUNC && arg0->val_real() >= 0)) && + arg1->type() == Item::FUNC_ITEM && + ((Item_func *) arg1)->functype() == Item_func::FT_FUNC) + cond_func= (Item_func_match *) arg1; } } else if (cond->type() == Item::COND_ITEM) From 679de2bb5eb36c900c0f9db189283e73ab4acbcc Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 21 Jan 2010 17:14:10 +0200 Subject: [PATCH 121/157] Bug #50276: Security flaw in INFORMATION_SCHEMA.TABLES check_access() returning false for a database does not guarantee that the access is granted to it. This wrong condition in filling the INFORMATION_SCHEMA tables causes extra tables to be returned to the user even if he has no rights to see them. Fixed by correcting the condition. --- mysql-test/r/information_schema.result | 22 +++++++++++++++++++++ mysql-test/t/information_schema.test | 27 ++++++++++++++++++++++++++ sql/sql_show.cc | 8 ++++---- 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 9a75e478264..4ed7e4e700b 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1725,4 +1725,26 @@ SELECT 'OK' AS TEST_RESULT FROM INFORMATION_SCHEMA.PROCESSLIST WHERE time < 0; TEST_RESULT OK SET TIMESTAMP=DEFAULT; +# +# Bug #50276: Security flaw in INFORMATION_SCHEMA.TABLES +# +CREATE DATABASE db1; +USE db1; +CREATE TABLE t1 (id INT); +CREATE USER nonpriv; +USE test; +# connected as nonpriv +# Should return 0 +SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1'; +COUNT(*) +0 +USE INFORMATION_SCHEMA; +# Should return 0 +SELECT COUNT(*) FROM TABLES WHERE TABLE_NAME='t1'; +COUNT(*) +0 +# connected as root +DROP USER nonpriv; +DROP TABLE db1.t1; +DROP DATABASE db1; End of 5.1 tests. diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 392d1062492..f3ce3d87252 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1419,6 +1419,33 @@ SET TIMESTAMP=@@TIMESTAMP + 10000000; SELECT 'OK' AS TEST_RESULT FROM INFORMATION_SCHEMA.PROCESSLIST WHERE time < 0; SET TIMESTAMP=DEFAULT; + +--echo # +--echo # Bug #50276: Security flaw in INFORMATION_SCHEMA.TABLES +--echo # +CREATE DATABASE db1; +USE db1; +CREATE TABLE t1 (id INT); +CREATE USER nonpriv; +USE test; + +connect (nonpriv_con, localhost, nonpriv,,); +connection nonpriv_con; +--echo # connected as nonpriv +--echo # Should return 0 +SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='t1'; +USE INFORMATION_SCHEMA; +--echo # Should return 0 +SELECT COUNT(*) FROM TABLES WHERE TABLE_NAME='t1'; + +connection default; +--echo # connected as root +disconnect nonpriv_con; +DROP USER nonpriv; +DROP TABLE db1.t1; +DROP DATABASE db1; + + --echo End of 5.1 tests. # Wait till all disconnects are completed diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 5ec40d4893c..989606300d8 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3367,11 +3367,11 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) while ((db_name= it++)) { #ifndef NO_EMBEDDED_ACCESS_CHECKS - if (!check_access(thd,SELECT_ACL, db_name->str, - &thd->col_access, 0, 1, with_i_schema) || + if (!(check_access(thd,SELECT_ACL, db_name->str, + &thd->col_access, 0, 1, with_i_schema) || + (!thd->col_access && check_grant_db(thd, db_name->str))) || sctx->master_access & (DB_ACLS | SHOW_DB_ACL) || - acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0) || - !check_grant_db(thd, db_name->str)) + acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0)) #endif { thd->no_warnings_for_error= 1; From 73f10f0662ce40b5cc6e8bc4d04f6cee45768ae7 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 21 Jan 2010 17:20:24 +0000 Subject: [PATCH 122/157] BUG#49481: RBR: MyISAM and bit fields may cause slave to stop on delete: cant find record Some engines return data for the record. Despite the fact that the null bit is set for some fields, their old value may still in the row. This can happen when unpacking an AI from the binlog on top of a previous record in which a field is set to NULL, which previously contained a value. Ultimately, this may cause the comparison of records to fail when the slave is doing an index or range scan. We fix this by deploying a call to reset() for each field that is set to null while unpacking a row from the binary log. Furthermore, we also add mixed mode test case to cover the scenario where updating and setting a field to null through a Query event and later searching it through a rows event will succeed. Finally, we also change the reset() method, from Field_bit class, so that it takes into account bits stored among the null bits and not only the ones stored in the record. mysql-test/suite/rpl/t/rpl_set_null_innodb.test: InnoDB test. mysql-test/suite/rpl/t/rpl_set_null_myisam.test: MyISAM test. mysql-test/suite/rpl_ndb/t/rpl_ndb_set_null.test: NDB test. sql/field.h: Changed reset so that it also clears the bits among the null_bits for the Field_bit class. sql/rpl_record.cc: Resetting field after setting it to null when unpacking row. --- mysql-test/extra/rpl_tests/rpl_set_null.test | 86 +++++++++++++++++++ .../suite/rpl/r/rpl_set_null_innodb.result | 35 ++++++++ .../suite/rpl/r/rpl_set_null_myisam.result | 35 ++++++++ .../suite/rpl/t/rpl_set_null_innodb.test | 6 ++ .../suite/rpl/t/rpl_set_null_myisam.test | 5 ++ .../suite/rpl_ndb/r/rpl_ndb_set_null.result | 35 ++++++++ .../suite/rpl_ndb/t/rpl_ndb_set_null.test | 6 ++ sql/field.h | 7 +- sql/rpl_record.cc | 11 +++ 9 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 mysql-test/extra/rpl_tests/rpl_set_null.test create mode 100644 mysql-test/suite/rpl/r/rpl_set_null_innodb.result create mode 100644 mysql-test/suite/rpl/r/rpl_set_null_myisam.result create mode 100644 mysql-test/suite/rpl/t/rpl_set_null_innodb.test create mode 100644 mysql-test/suite/rpl/t/rpl_set_null_myisam.test create mode 100644 mysql-test/suite/rpl_ndb/r/rpl_ndb_set_null.result create mode 100644 mysql-test/suite/rpl_ndb/t/rpl_ndb_set_null.test diff --git a/mysql-test/extra/rpl_tests/rpl_set_null.test b/mysql-test/extra/rpl_tests/rpl_set_null.test new file mode 100644 index 00000000000..f2aba089279 --- /dev/null +++ b/mysql-test/extra/rpl_tests/rpl_set_null.test @@ -0,0 +1,86 @@ +# Both of the following tests check that comparison of binlog BI +# against SE record will not fail due to remains from previous values +# in the SE record (before a given field was set to null). +# +# In MIXED mode: +# - Insert and update are executed as statements +# - Delete is executed as a row event +# - Assertion: checks that comparison will not fail because the update +# statement will clear the record contents for the nulled +# field. If data was not cleared, some engines may keep +# the value and return it later as garbage - despite the +# fact that field is null. This may cause slave to +# falsely fail in the comparison (memcmp would fail +# because of "garbage" in record data). +# +# In ROW mode: +# - Insert, update and delete are executed as row events. +# - Assertion: checks that comparison will not fail because the update +# rows event will clear the record contents before +# feeding the new value to the SE. This protects against +# SEs that do not clear record contents when storing +# nulled fields. If the engine did not clear the data it +# would cause slave to falsely fail in the comparison +# (memcmp would fail because of "garbage" in record +# data). This scenario is pretty much the same described +# above in MIXED mode, but checks different execution +# path in the slave. + +# BUG#49481: RBR: MyISAM and bit fields may cause slave to stop on +# delete cant find record + +-- source include/master-slave-reset.inc + +-- connection master +-- eval CREATE TABLE t1 (c1 BIT, c2 INT) Engine=$engine +INSERT INTO `t1` VALUES ( 1, 1 ); +UPDATE t1 SET c1=NULL where c2=1; +-- sync_slave_with_master + +-- let $diff_table_1=master:test.t1 +-- let $diff_table_2=slave:test.t1 +-- source include/diff_tables.inc + +-- connection master +# triggers switch to row mode when on mixed +DELETE FROM t1 WHERE c2=1 LIMIT 1; +-- sync_slave_with_master + +-- let $diff_table_1=master:test.t1 +-- let $diff_table_2=slave:test.t1 +-- source include/diff_tables.inc + +-- connection master +DROP TABLE t1; +-- sync_slave_with_master + +-- source include/master-slave-reset.inc + +-- connection master + +# BUG#49482: RBR: Replication may break on deletes when MyISAM tables +# + char field are used + +-- eval CREATE TABLE t1 (c1 CHAR) Engine=$engine + +INSERT INTO t1 ( c1 ) VALUES ( 'w' ) ; +SELECT * FROM t1; +UPDATE t1 SET c1=NULL WHERE c1='w'; +-- sync_slave_with_master + +-- let $diff_table_1=master:test.t1 +-- let $diff_table_2=slave:test.t1 +-- source include/diff_tables.inc + +-- connection master +# triggers switch to row mode when on mixed +DELETE FROM t1 LIMIT 2; +-- sync_slave_with_master + +-- let $diff_table_1=master:test.t1 +-- let $diff_table_2=slave:test.t1 +-- source include/diff_tables.inc + +-- connection master +DROP TABLE t1; +-- sync_slave_with_master diff --git a/mysql-test/suite/rpl/r/rpl_set_null_innodb.result b/mysql-test/suite/rpl/r/rpl_set_null_innodb.result new file mode 100644 index 00000000000..41600a5fe1b --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_set_null_innodb.result @@ -0,0 +1,35 @@ +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; +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; +CREATE TABLE t1 (c1 BIT, c2 INT) Engine=InnoDB; +INSERT INTO `t1` VALUES ( 1, 1 ); +UPDATE t1 SET c1=NULL where c2=1; +Comparing tables master:test.t1 and slave:test.t1 +DELETE FROM t1 WHERE c2=1 LIMIT 1; +Comparing tables master:test.t1 and slave:test.t1 +DROP TABLE t1; +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; +CREATE TABLE t1 (c1 CHAR) Engine=InnoDB; +INSERT INTO t1 ( c1 ) VALUES ( 'w' ) ; +SELECT * FROM t1; +c1 +w +UPDATE t1 SET c1=NULL WHERE c1='w'; +Comparing tables master:test.t1 and slave:test.t1 +DELETE FROM t1 LIMIT 2; +Comparing tables master:test.t1 and slave:test.t1 +DROP TABLE t1; diff --git a/mysql-test/suite/rpl/r/rpl_set_null_myisam.result b/mysql-test/suite/rpl/r/rpl_set_null_myisam.result new file mode 100644 index 00000000000..cbd7010664a --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_set_null_myisam.result @@ -0,0 +1,35 @@ +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; +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; +CREATE TABLE t1 (c1 BIT, c2 INT) Engine=MyISAM; +INSERT INTO `t1` VALUES ( 1, 1 ); +UPDATE t1 SET c1=NULL where c2=1; +Comparing tables master:test.t1 and slave:test.t1 +DELETE FROM t1 WHERE c2=1 LIMIT 1; +Comparing tables master:test.t1 and slave:test.t1 +DROP TABLE t1; +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; +CREATE TABLE t1 (c1 CHAR) Engine=MyISAM; +INSERT INTO t1 ( c1 ) VALUES ( 'w' ) ; +SELECT * FROM t1; +c1 +w +UPDATE t1 SET c1=NULL WHERE c1='w'; +Comparing tables master:test.t1 and slave:test.t1 +DELETE FROM t1 LIMIT 2; +Comparing tables master:test.t1 and slave:test.t1 +DROP TABLE t1; diff --git a/mysql-test/suite/rpl/t/rpl_set_null_innodb.test b/mysql-test/suite/rpl/t/rpl_set_null_innodb.test new file mode 100644 index 00000000000..dba79b78fa1 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_set_null_innodb.test @@ -0,0 +1,6 @@ +-- source include/have_binlog_format_mixed_or_row.inc +-- source include/master-slave.inc +-- source include/have_innodb.inc + +-- let $engine= InnoDB +-- source extra/rpl_tests/rpl_set_null.test diff --git a/mysql-test/suite/rpl/t/rpl_set_null_myisam.test b/mysql-test/suite/rpl/t/rpl_set_null_myisam.test new file mode 100644 index 00000000000..7b433071553 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_set_null_myisam.test @@ -0,0 +1,5 @@ +-- source include/have_binlog_format_mixed_or_row.inc +-- source include/master-slave.inc + +-- let $engine= MyISAM +-- source extra/rpl_tests/rpl_set_null.test diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_set_null.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_set_null.result new file mode 100644 index 00000000000..473cd63169c --- /dev/null +++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_set_null.result @@ -0,0 +1,35 @@ +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; +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; +CREATE TABLE t1 (c1 BIT, c2 INT) Engine=NDB; +INSERT INTO `t1` VALUES ( 1, 1 ); +UPDATE t1 SET c1=NULL where c2=1; +Comparing tables master:test.t1 and slave:test.t1 +DELETE FROM t1 WHERE c2=1 LIMIT 1; +Comparing tables master:test.t1 and slave:test.t1 +DROP TABLE t1; +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; +CREATE TABLE t1 (c1 CHAR) Engine=NDB; +INSERT INTO t1 ( c1 ) VALUES ( 'w' ) ; +SELECT * FROM t1; +c1 +w +UPDATE t1 SET c1=NULL WHERE c1='w'; +Comparing tables master:test.t1 and slave:test.t1 +DELETE FROM t1 LIMIT 2; +Comparing tables master:test.t1 and slave:test.t1 +DROP TABLE t1; diff --git a/mysql-test/suite/rpl_ndb/t/rpl_ndb_set_null.test b/mysql-test/suite/rpl_ndb/t/rpl_ndb_set_null.test new file mode 100644 index 00000000000..454807d9591 --- /dev/null +++ b/mysql-test/suite/rpl_ndb/t/rpl_ndb_set_null.test @@ -0,0 +1,6 @@ +-- source include/have_ndb.inc +-- source include/have_binlog_format_mixed_or_row.inc +-- source include/ndb_master-slave.inc + +-- let $engine= NDB +-- source extra/rpl_tests/rpl_set_null.test diff --git a/sql/field.h b/sql/field.h index ae074cc1a30..55604193687 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1926,7 +1926,12 @@ public: uint32 max_display_length() { return field_length; } uint size_of() const { return sizeof(*this); } Item_result result_type () const { return INT_RESULT; } - int reset(void) { bzero(ptr, bytes_in_rec); return 0; } + int reset(void) { + bzero(ptr, bytes_in_rec); + if (bit_ptr && (bit_len > 0)) // reset odd bits among null bits + clr_rec_bits(bit_ptr, bit_ofs, bit_len); + return 0; + } int store(const char *to, uint length, CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc index 8e80620dd2c..f6bf57cde3e 100644 --- a/sql/rpl_record.cc +++ b/sql/rpl_record.cc @@ -231,6 +231,17 @@ unpack_row(Relay_log_info const *rli, { DBUG_PRINT("debug", ("Was NULL; null mask: 0x%x; null bits: 0x%x", null_mask, null_bits)); + /** + Calling reset just in case one is unpacking on top a + record with data. + + This could probably go into set_null() but doing so, + (i) triggers assertion in other parts of the code at + the moment; (ii) it would make us reset the field, + always when setting null, which right now doesn't seem + needed anywhere else except here. + */ + f->reset(); f->set_null(); } else From f42a200e9e1e535dcf647237fcb4ccb65c04965d Mon Sep 17 00:00:00 2001 From: Magne Mahre Date: Fri, 22 Jan 2010 10:37:44 +0100 Subject: [PATCH 123/157] Post-commit fix of two tests The WL#5154 commit added a couple of warning messages that was not fixed in the result files for two RPL tests. --- mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result | 2 ++ mysql-test/suite/rpl/r/rpl_sp.result | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result b/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result index 2cb316c6a1f..449407742de 100644 --- a/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result +++ b/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result @@ -152,6 +152,7 @@ c1 c3 c4 c5 5 2006-02-22 00:00:00 Tested in Texas 11 --- Test 2 position test -- +Warning: The option '--position' is deprecated and will be removed in MySQL 5.6. Please use --start-position instead. /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -314,6 +315,7 @@ ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- Test 7 reading stdin w/position -- +Warning: The option '--position' is deprecated and will be removed in MySQL 5.6. Please use --start-position instead. /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; diff --git a/mysql-test/suite/rpl/r/rpl_sp.result b/mysql-test/suite/rpl/r/rpl_sp.result index 90a362c352b..7fedaf4c1ef 100644 --- a/mysql-test/suite/rpl/r/rpl_sp.result +++ b/mysql-test/suite/rpl/r/rpl_sp.result @@ -195,7 +195,7 @@ set @old_log_bin_trust_routine_creators= @@global.log_bin_trust_routine_creators set @old_log_bin_trust_function_creators= @@global.log_bin_trust_function_creators; set global log_bin_trust_routine_creators=1; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.6. Please use '@@log_bin_trust_function_creators' instead set global log_bin_trust_function_creators=0; set global log_bin_trust_function_creators=1; set @old_log_bin_trust_routine_creators= @@global.log_bin_trust_routine_creators; @@ -559,11 +559,11 @@ end master-bin.000001 # Query 1 # use `mysqltest`; SELECT `mysqltest2`.`f1`() set @@global.log_bin_trust_routine_creators= @old_log_bin_trust_routine_creators; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.6. Please use '@@log_bin_trust_function_creators' instead set @@global.log_bin_trust_function_creators= @old_log_bin_trust_function_creators; set @@global.log_bin_trust_routine_creators= @old_log_bin_trust_routine_creators; Warnings: -Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 6.0. Please use '@@log_bin_trust_function_creators' instead +Warning 1287 The syntax '@@log_bin_trust_routine_creators' is deprecated and will be removed in MySQL 5.6. Please use '@@log_bin_trust_function_creators' instead set @@global.log_bin_trust_function_creators= @old_log_bin_trust_function_creators; drop database mysqltest; drop database mysqltest2; From 3cae7d1187795a8089b6f54ac60cf2a0e579cf89 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Jan 2010 17:38:21 +0800 Subject: [PATCH 124/157] Bug #49132 Replication failure on temporary table + DDL In RBR, DDL statement will change binlog format to non row-based format before it is binlogged, but the binlog format was not be restored, and then manipulating a temporary table can not reset binlog format to row-based format rightly. So that the manipulated statement is binlogged with statement-based format. To fix the problem, restore the state of binlog format after the DDL statement is binlogged. mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test: Added the test file to verify if executing DDL statement before trying to manipulate a temporary table causes row-based replication to break with error 'table does not exist'. mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result: Correct the test result, all the above binlog event should be row-based after the bug49132 is fixed IN RBR. mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result: Test result for bug#49132 base on ndb engine. mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test: Added the test file to verify if executing DDL statement before trying to manipulate a temporary table causes row-based replication to break with error 'table does not exist' base on ndb engine. mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result: Test result for bug#49132 base on myisam engine. mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test: Added the test file to verify if executing DDL statement before trying to manipulate a temporary table causes row-based replication to break with error 'table does not exist' base on myisam engine. sql/event_db_repository.cc: Added code to restore the state of binlog format after the DDL statement is binlogged. sql/events.cc: Added code to restore the state of binlog format after the DDL statement is binlogged. sql/sp.cc: Added code to restore the state of binlog format after the DDL statement is binlogged. sql/sql_acl.cc: Added code to restore the state of binlog format after the DDL statement is binlogged. sql/sql_udf.cc: Added code to restore the state of binlog format after the DDL statement is binlogged. --- .../rpl_tests/rpl_tmp_table_and_DDL.test | 159 ++++++++++++++++++ .../r/binlog_row_mix_innodb_myisam.result | 64 ++++--- .../suite/ndb/r/ndb_tmp_table_and_DDL.result | 90 ++++++++++ .../suite/ndb/t/ndb_tmp_table_and_DDL.test | 11 ++ .../suite/rpl/r/rpl_tmp_table_and_DDL.result | 96 +++++++++++ .../suite/rpl/t/rpl_tmp_table_and_DDL.test | 13 ++ sql/event_db_repository.cc | 7 +- sql/events.cc | 23 ++- sql/sp.cc | 13 ++ sql/sql_acl.cc | 66 ++++++++ sql/sql_udf.cc | 18 +- 11 files changed, 526 insertions(+), 34 deletions(-) create mode 100644 mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test create mode 100644 mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result create mode 100644 mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test create mode 100644 mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result create mode 100644 mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test diff --git a/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test b/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test new file mode 100644 index 00000000000..9cf287281a0 --- /dev/null +++ b/mysql-test/extra/rpl_tests/rpl_tmp_table_and_DDL.test @@ -0,0 +1,159 @@ +# +# This test verify if executing DDL statement before trying to manipulate +# a temporary table causes row-based replication to break with error 'table +# does not exist'. +# + +# CREATE TABLE when a temporary table is open. +CREATE TEMPORARY TABLE t1 (a INT); +EVAL CREATE TABLE t2 (a INT, b INT) ENGINE= $ENGINE_TYPE; +INSERT INTO t1 VALUES (1); + +# CREATE EVENT when a temporary table is open. +CREATE EVENT e1 ON SCHEDULE EVERY 10 HOUR DO SELECT 1; +INSERT INTO t1 VALUES (1); + +# ALTER EVENT when a temporary table is open. +ALTER EVENT e1 ON SCHEDULE EVERY 20 HOUR DO SELECT 1; +INSERT INTO t1 VALUES (1); + +# DROP EVENT when a temporary table is open. +DROP EVENT IF EXISTS e1; +INSERT INTO t1 VALUES (1); + +# CREATE PROCEDURE when a temporary table is open. +CREATE PROCEDURE p1() SELECT 1; +INSERT INTO t1 VALUES (1); + +# Alter PROCEDURE when a temporary table is open. +ALTER PROCEDURE p1 SQL SECURITY INVOKER; +INSERT INTO t1 VALUES (1); + +# CREATE FUNCTION when a temporary table is open. +CREATE FUNCTION f1() RETURNS INT RETURN 123; +INSERT INTO t1 VALUES (1); + +# ALTER FUNCTION when a temporary table is open. +ALTER FUNCTION f1 SQL SECURITY INVOKER; +INSERT INTO t1 VALUES (1); + +# CREATE DATABASE when a temporary table is open. +CREATE DATABASE mysqltest1; +INSERT INTO t1 VALUES (1); + +# DROP DATABASE when a temporary table is open. +DROP DATABASE mysqltest1; +INSERT INTO t1 VALUES (1); + +# CREATE USER when a temporary table is open. +CREATE USER test_1@localhost; +INSERT INTO t1 VALUES (1); + +# GRANT select on table to user when a temporary table is open. +GRANT SELECT ON t2 TO test_1@localhost; +INSERT INTO t1 VALUES (1); + +# GRANT all on function to user when a temporary table is open. +GRANT ALL ON f1 TO test_1@localhost; +INSERT INTO t1 VALUES (1); + +# GRANT all on procedure to user when a temporary table is open. +GRANT ALL ON p1 TO test_1@localhost; +INSERT INTO t1 VALUES (1); + +# GRANT usage on *.* to user when a temporary table is open. +GRANT USAGE ON *.* TO test_1@localhost; +INSERT INTO t1 VALUES (1); + +# REVOKE ALL PRIVILEGES on function to user when a temporary table is open. +REVOKE ALL PRIVILEGES ON f1 FROM test_1@localhost; +INSERT INTO t1 VALUES (1); + +# REVOKE ALL PRIVILEGES on procedure to user when a temporary table is open. +REVOKE ALL PRIVILEGES ON p1 FROM test_1@localhost; +INSERT INTO t1 VALUES (1); + +# REVOKE ALL PRIVILEGES on table to user when a temporary table is open. +REVOKE ALL PRIVILEGES ON t2 FROM test_1@localhost; +INSERT INTO t1 VALUES (1); + +# REVOKE usage on *.* from user when a temporary table is open. +REVOKE USAGE ON *.* FROM test_1@localhost; +INSERT INTO t1 VALUES (1); + +# RENAME USER when a temporary table is open. +RENAME USER test_1@localhost TO test_2@localhost; +INSERT INTO t1 VALUES (1); + +# DROP USER when a temporary table is open. +DROP USER test_2@localhost; +INSERT INTO t1 VALUES (1); + +# Test ACL statement in sub statement +DELIMITER |; +CREATE PROCEDURE p2() +BEGIN + # CREATE USER when a temporary table is open. + CREATE TEMPORARY TABLE t3 (a INT); + CREATE USER test_2@localhost; + INSERT INTO t1 VALUES (1); + + # GRANT select on table to user when a temporary table is open. + GRANT SELECT ON t2 TO test_2@localhost; + INSERT INTO t1 VALUES (1); + + # GRANT all on function to user when a temporary table is open. + GRANT ALL ON f1 TO test_2@localhost; + INSERT INTO t1 VALUES (1); + + # GRANT all on procedure to user when a temporary table is open. + GRANT ALL ON p1 TO test_2@localhost; + INSERT INTO t1 VALUES (1); + + # GRANT usage on *.* to user when a temporary table is open. + GRANT USAGE ON *.* TO test_2@localhost; + INSERT INTO t1 VALUES (1); + + # REVOKE ALL PRIVILEGES on function to user when a temporary table is open. + REVOKE ALL PRIVILEGES ON f1 FROM test_2@localhost; + INSERT INTO t1 VALUES (1); + + # REVOKE ALL PRIVILEGES on procedure to user when a temporary table is open. + REVOKE ALL PRIVILEGES ON p1 FROM test_2@localhost; + INSERT INTO t1 VALUES (1); + + # REVOKE ALL PRIVILEGES on table to user when a temporary table is open. + REVOKE ALL PRIVILEGES ON t2 FROM test_2@localhost; + INSERT INTO t1 VALUES (1); + + # REVOKE usage on *.* from user when a temporary table is open. + REVOKE USAGE ON *.* FROM test_2@localhost; + INSERT INTO t1 VALUES (1); + + # RENAME USER when a temporary table is open. + RENAME USER test_2@localhost TO test_3@localhost; + INSERT INTO t1 VALUES (1); + + # DROP USER when a temporary table is open. + DROP USER test_3@localhost; + INSERT INTO t1 VALUES (1); + DROP TEMPORARY TABLE t3; +END | +DELIMITER ;| + +# DROP PROCEDURE when a temporary table is open. +DROP PROCEDURE p1; +INSERT INTO t1 VALUES (1); +DROP PROCEDURE p2; +INSERT INTO t1 VALUES (1); + +# DROP FUNCTION when a temporary table is open. +DROP FUNCTION f1; +INSERT INTO t1 VALUES (1); + +# DROP TABLE when a temporary table is open. +DROP TABLE t2; +INSERT INTO t1 VALUES (1); + +DROP TEMPORARY TABLE t1; + diff --git a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result index ef98275041c..87e9b7f8685 100644 --- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result @@ -772,8 +772,11 @@ insert into t2 values (bug27417(2)); ERROR 23000: Duplicate entry '2' for key 'PRIMARY' show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Intvar # # INSERT_ID=3 -master-bin.000001 # Query # # use `test`; insert into t2 values (bug27417(2)) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK select count(*) from t1 /* must be 3 */; count(*) 3 @@ -787,8 +790,11 @@ count(*) 2 show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Intvar # # INSERT_ID=4 -master-bin.000001 # Query # # use `test`; delete from t2 where a=bug27417(3) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # COMMIT select count(*) from t1 /* must be 5 */; count(*) 5 @@ -810,8 +816,9 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY' show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # BEGIN -master-bin.000001 # Intvar # # INSERT_ID=1 -master-bin.000001 # Query # # use `test`; insert into t2 values (bug27417(1)) +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # ROLLBACK select count(*) from t1 /* must be 1 */; count(*) @@ -825,8 +832,10 @@ ERROR 23000: Duplicate entry '2' for key 'PRIMARY' show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # BEGIN -master-bin.000001 # Intvar # # INSERT_ID=2 -master-bin.000001 # Query # # use `test`; insert into t2 select bug27417(1) union select bug27417(2) +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # ROLLBACK select count(*) from t1 /* must be 2 */; count(*) @@ -838,8 +847,13 @@ update t3 set b=b+bug27417(1); ERROR 23000: Duplicate entry '4' for key 'b' show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 # Intvar # # INSERT_ID=4 -master-bin.000001 # Query # # use `test`; update t3 set b=b+bug27417(1) +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Table_map # # table_id: # (test.t3) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Update_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F +master-bin.000001 # Query # # ROLLBACK select count(*) from t1 /* must be 2 */; count(*) 2 @@ -853,8 +867,9 @@ ERROR 23000: Duplicate entry '2' for key 'PRIMARY' show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # BEGIN -master-bin.000001 # Intvar # # INSERT_ID=6 -master-bin.000001 # Query # # use `test`; UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */ +master-bin.000001 # Table_map # # table_id: # (test.t4) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # ROLLBACK select count(*) from t1 /* must be 4 */; count(*) @@ -869,7 +884,7 @@ UPDATE t3,t4 SET t3.a=t4.a + bug27417(1); ERROR 23000: Duplicate entry '2' for key 'PRIMARY' select count(*) from t1 /* must be 1 */; count(*) -1 +2 drop table t4; delete from t1; delete from t2; @@ -884,8 +899,10 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY' show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # BEGIN -master-bin.000001 # Intvar # # INSERT_ID=9 -master-bin.000001 # Query # # use `test`; delete from t2 +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Table_map # # table_id: # (test.t3) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # ROLLBACK select count(*) from t1 /* must be 1 */; count(*) @@ -904,7 +921,11 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY' show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # BEGIN -master-bin.000001 # Query # # use `test`; delete t2.* from t2,t5 where t2.a=t5.a + 1 +master-bin.000001 # Table_map # # table_id: # (test.t2) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Delete_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # ROLLBACK select count(*) from t1 /* must be 1 */; count(*) @@ -924,12 +945,11 @@ count(*) show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # BEGIN -master-bin.000001 # Intvar # # INSERT_ID=10 -master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci -master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# -master-bin.000001 # Intvar # # INSERT_ID=10 -master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=# +master-bin.000001 # Table_map # # table_id: # (test.t4) +master-bin.000001 # Table_map # # table_id: # (test.t1) +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # +master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # ROLLBACK drop trigger trg_del_t2; drop table t1,t2,t3,t4,t5; diff --git a/mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result b/mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result new file mode 100644 index 00000000000..1b0f718ad65 --- /dev/null +++ b/mysql-test/suite/ndb/r/ndb_tmp_table_and_DDL.result @@ -0,0 +1,90 @@ +CREATE TEMPORARY TABLE t1 (a INT); +CREATE TABLE t2 (a INT, b INT) ENGINE= NDB; +INSERT INTO t1 VALUES (1); +CREATE EVENT e1 ON SCHEDULE EVERY 10 HOUR DO SELECT 1; +INSERT INTO t1 VALUES (1); +ALTER EVENT e1 ON SCHEDULE EVERY 20 HOUR DO SELECT 1; +INSERT INTO t1 VALUES (1); +DROP EVENT IF EXISTS e1; +INSERT INTO t1 VALUES (1); +CREATE PROCEDURE p1() SELECT 1; +INSERT INTO t1 VALUES (1); +ALTER PROCEDURE p1 SQL SECURITY INVOKER; +INSERT INTO t1 VALUES (1); +CREATE FUNCTION f1() RETURNS INT RETURN 123; +INSERT INTO t1 VALUES (1); +ALTER FUNCTION f1 SQL SECURITY INVOKER; +INSERT INTO t1 VALUES (1); +CREATE DATABASE mysqltest1; +INSERT INTO t1 VALUES (1); +DROP DATABASE mysqltest1; +INSERT INTO t1 VALUES (1); +CREATE USER test_1@localhost; +INSERT INTO t1 VALUES (1); +GRANT SELECT ON t2 TO test_1@localhost; +INSERT INTO t1 VALUES (1); +GRANT ALL ON f1 TO test_1@localhost; +INSERT INTO t1 VALUES (1); +GRANT ALL ON p1 TO test_1@localhost; +INSERT INTO t1 VALUES (1); +GRANT USAGE ON *.* TO test_1@localhost; +INSERT INTO t1 VALUES (1); +REVOKE ALL PRIVILEGES ON f1 FROM test_1@localhost; +INSERT INTO t1 VALUES (1); +REVOKE ALL PRIVILEGES ON p1 FROM test_1@localhost; +INSERT INTO t1 VALUES (1); +REVOKE ALL PRIVILEGES ON t2 FROM test_1@localhost; +INSERT INTO t1 VALUES (1); +REVOKE USAGE ON *.* FROM test_1@localhost; +INSERT INTO t1 VALUES (1); +RENAME USER test_1@localhost TO test_2@localhost; +INSERT INTO t1 VALUES (1); +DROP USER test_2@localhost; +INSERT INTO t1 VALUES (1); +CREATE PROCEDURE p2() +BEGIN +# CREATE USER when a temporary table is open. +CREATE TEMPORARY TABLE t3 (a INT); +CREATE USER test_2@localhost; +INSERT INTO t1 VALUES (1); +# GRANT select on table to user when a temporary table is open. +GRANT SELECT ON t2 TO test_2@localhost; +INSERT INTO t1 VALUES (1); +# GRANT all on function to user when a temporary table is open. +GRANT ALL ON f1 TO test_2@localhost; +INSERT INTO t1 VALUES (1); +# GRANT all on procedure to user when a temporary table is open. +GRANT ALL ON p1 TO test_2@localhost; +INSERT INTO t1 VALUES (1); +# GRANT usage on *.* to user when a temporary table is open. +GRANT USAGE ON *.* TO test_2@localhost; +INSERT INTO t1 VALUES (1); +# REVOKE ALL PRIVILEGES on function to user when a temporary table is open. +REVOKE ALL PRIVILEGES ON f1 FROM test_2@localhost; +INSERT INTO t1 VALUES (1); +# REVOKE ALL PRIVILEGES on procedure to user when a temporary table is open. +REVOKE ALL PRIVILEGES ON p1 FROM test_2@localhost; +INSERT INTO t1 VALUES (1); +# REVOKE ALL PRIVILEGES on table to user when a temporary table is open. +REVOKE ALL PRIVILEGES ON t2 FROM test_2@localhost; +INSERT INTO t1 VALUES (1); +# REVOKE usage on *.* from user when a temporary table is open. +REVOKE USAGE ON *.* FROM test_2@localhost; +INSERT INTO t1 VALUES (1); +# RENAME USER when a temporary table is open. +RENAME USER test_2@localhost TO test_3@localhost; +INSERT INTO t1 VALUES (1); +# DROP USER when a temporary table is open. +DROP USER test_3@localhost; +INSERT INTO t1 VALUES (1); +DROP TEMPORARY TABLE t3; +END | +DROP PROCEDURE p1; +INSERT INTO t1 VALUES (1); +DROP PROCEDURE p2; +INSERT INTO t1 VALUES (1); +DROP FUNCTION f1; +INSERT INTO t1 VALUES (1); +DROP TABLE t2; +INSERT INTO t1 VALUES (1); +DROP TEMPORARY TABLE t1; diff --git a/mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test b/mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test new file mode 100644 index 00000000000..748c0ac28e4 --- /dev/null +++ b/mysql-test/suite/ndb/t/ndb_tmp_table_and_DDL.test @@ -0,0 +1,11 @@ +# +# Bug#49132 +# This test verifies if executing DDL statement before trying to manipulate +# a temporary table causes row-based replication to break with error 'table +# does not exist' base on ndb engine. +# + +source include/have_ndb.inc; + +LET $ENGINE_TYPE= NDB; +source extra/rpl_tests/rpl_tmp_table_and_DDL.test; diff --git a/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result b/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result new file mode 100644 index 00000000000..5729faa9659 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_tmp_table_and_DDL.result @@ -0,0 +1,96 @@ +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; +CREATE TEMPORARY TABLE t1 (a INT); +CREATE TABLE t2 (a INT, b INT) ENGINE= MyISAM; +INSERT INTO t1 VALUES (1); +CREATE EVENT e1 ON SCHEDULE EVERY 10 HOUR DO SELECT 1; +INSERT INTO t1 VALUES (1); +ALTER EVENT e1 ON SCHEDULE EVERY 20 HOUR DO SELECT 1; +INSERT INTO t1 VALUES (1); +DROP EVENT IF EXISTS e1; +INSERT INTO t1 VALUES (1); +CREATE PROCEDURE p1() SELECT 1; +INSERT INTO t1 VALUES (1); +ALTER PROCEDURE p1 SQL SECURITY INVOKER; +INSERT INTO t1 VALUES (1); +CREATE FUNCTION f1() RETURNS INT RETURN 123; +INSERT INTO t1 VALUES (1); +ALTER FUNCTION f1 SQL SECURITY INVOKER; +INSERT INTO t1 VALUES (1); +CREATE DATABASE mysqltest1; +INSERT INTO t1 VALUES (1); +DROP DATABASE mysqltest1; +INSERT INTO t1 VALUES (1); +CREATE USER test_1@localhost; +INSERT INTO t1 VALUES (1); +GRANT SELECT ON t2 TO test_1@localhost; +INSERT INTO t1 VALUES (1); +GRANT ALL ON f1 TO test_1@localhost; +INSERT INTO t1 VALUES (1); +GRANT ALL ON p1 TO test_1@localhost; +INSERT INTO t1 VALUES (1); +GRANT USAGE ON *.* TO test_1@localhost; +INSERT INTO t1 VALUES (1); +REVOKE ALL PRIVILEGES ON f1 FROM test_1@localhost; +INSERT INTO t1 VALUES (1); +REVOKE ALL PRIVILEGES ON p1 FROM test_1@localhost; +INSERT INTO t1 VALUES (1); +REVOKE ALL PRIVILEGES ON t2 FROM test_1@localhost; +INSERT INTO t1 VALUES (1); +REVOKE USAGE ON *.* FROM test_1@localhost; +INSERT INTO t1 VALUES (1); +RENAME USER test_1@localhost TO test_2@localhost; +INSERT INTO t1 VALUES (1); +DROP USER test_2@localhost; +INSERT INTO t1 VALUES (1); +CREATE PROCEDURE p2() +BEGIN +# CREATE USER when a temporary table is open. +CREATE TEMPORARY TABLE t3 (a INT); +CREATE USER test_2@localhost; +INSERT INTO t1 VALUES (1); +# GRANT select on table to user when a temporary table is open. +GRANT SELECT ON t2 TO test_2@localhost; +INSERT INTO t1 VALUES (1); +# GRANT all on function to user when a temporary table is open. +GRANT ALL ON f1 TO test_2@localhost; +INSERT INTO t1 VALUES (1); +# GRANT all on procedure to user when a temporary table is open. +GRANT ALL ON p1 TO test_2@localhost; +INSERT INTO t1 VALUES (1); +# GRANT usage on *.* to user when a temporary table is open. +GRANT USAGE ON *.* TO test_2@localhost; +INSERT INTO t1 VALUES (1); +# REVOKE ALL PRIVILEGES on function to user when a temporary table is open. +REVOKE ALL PRIVILEGES ON f1 FROM test_2@localhost; +INSERT INTO t1 VALUES (1); +# REVOKE ALL PRIVILEGES on procedure to user when a temporary table is open. +REVOKE ALL PRIVILEGES ON p1 FROM test_2@localhost; +INSERT INTO t1 VALUES (1); +# REVOKE ALL PRIVILEGES on table to user when a temporary table is open. +REVOKE ALL PRIVILEGES ON t2 FROM test_2@localhost; +INSERT INTO t1 VALUES (1); +# REVOKE usage on *.* from user when a temporary table is open. +REVOKE USAGE ON *.* FROM test_2@localhost; +INSERT INTO t1 VALUES (1); +# RENAME USER when a temporary table is open. +RENAME USER test_2@localhost TO test_3@localhost; +INSERT INTO t1 VALUES (1); +# DROP USER when a temporary table is open. +DROP USER test_3@localhost; +INSERT INTO t1 VALUES (1); +DROP TEMPORARY TABLE t3; +END | +DROP PROCEDURE p1; +INSERT INTO t1 VALUES (1); +DROP PROCEDURE p2; +INSERT INTO t1 VALUES (1); +DROP FUNCTION f1; +INSERT INTO t1 VALUES (1); +DROP TABLE t2; +INSERT INTO t1 VALUES (1); +DROP TEMPORARY TABLE t1; diff --git a/mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test b/mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test new file mode 100644 index 00000000000..56924a2efe9 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_tmp_table_and_DDL.test @@ -0,0 +1,13 @@ +# +# Bug#49132 +# This test verifies if executing DDL statement before trying to manipulate +# a temporary table causes row-based replication to break with error 'table +# does not exist' base on myisam engine. +# + +source include/master-slave.inc; +source include/have_binlog_format_row.inc; + +LET $ENGINE_TYPE= MyISAM; +source extra/rpl_tests/rpl_tmp_table_and_DDL.test; + diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index 9f3863eb2b0..753e9d21b65 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -1045,6 +1045,7 @@ update_timing_fields_for_event(THD *thd, TABLE *table= NULL; Field **fields; int ret= 1; + bool save_binlog_row_based; DBUG_ENTER("Event_db_repository::update_timing_fields_for_event"); @@ -1052,8 +1053,8 @@ update_timing_fields_for_event(THD *thd, Turn off row binlogging of event timing updates. These are not used for RBR of events replicated to the slave. */ - if (thd->current_stmt_binlog_row_based) - thd->clear_current_stmt_binlog_row_based(); + save_binlog_row_based= thd->current_stmt_binlog_row_based; + thd->clear_current_stmt_binlog_row_based(); DBUG_ASSERT(thd->security_ctx->master_access & SUPER_ACL); @@ -1095,6 +1096,8 @@ update_timing_fields_for_event(THD *thd, end: if (table) close_thread_tables(thd); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(test(ret)); } diff --git a/sql/events.cc b/sql/events.cc index 790e6a61699..c3a57578f2b 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -389,6 +389,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, bool if_not_exists) { int ret; + bool save_binlog_row_based; DBUG_ENTER("Events::create_event"); /* @@ -431,8 +432,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, Turn off row binlogging of this statement and use statement-based so that all supporting tables are updated for CREATE EVENT command. */ - if (thd->current_stmt_binlog_row_based) - thd->clear_current_stmt_binlog_row_based(); + save_binlog_row_based= thd->current_stmt_binlog_row_based; + thd->clear_current_stmt_binlog_row_based(); pthread_mutex_lock(&LOCK_event_metadata); @@ -472,6 +473,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, { sql_print_error("Event Error: An error occurred while creating query string, " "before writing it into binary log."); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(TRUE); } /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER @@ -480,6 +483,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, } } pthread_mutex_unlock(&LOCK_event_metadata); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(ret); } @@ -509,6 +514,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, LEX_STRING *new_dbname, LEX_STRING *new_name) { int ret; + bool save_binlog_row_based; Event_queue_element *new_element; DBUG_ENTER("Events::update_event"); @@ -565,8 +571,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, Turn off row binlogging of this statement and use statement-based so that all supporting tables are updated for UPDATE EVENT command. */ - if (thd->current_stmt_binlog_row_based) - thd->clear_current_stmt_binlog_row_based(); + save_binlog_row_based= thd->current_stmt_binlog_row_based; + thd->clear_current_stmt_binlog_row_based(); pthread_mutex_lock(&LOCK_event_metadata); @@ -602,6 +608,8 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, } } pthread_mutex_unlock(&LOCK_event_metadata); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(ret); } @@ -635,6 +643,7 @@ bool Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) { int ret; + bool save_binlog_row_based; DBUG_ENTER("Events::drop_event"); /* @@ -662,8 +671,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) Turn off row binlogging of this statement and use statement-based so that all supporting tables are updated for DROP EVENT command. */ - if (thd->current_stmt_binlog_row_based) - thd->clear_current_stmt_binlog_row_based(); + save_binlog_row_based= thd->current_stmt_binlog_row_based; + thd->clear_current_stmt_binlog_row_based(); pthread_mutex_lock(&LOCK_event_metadata); /* On error conditions my_error() is called so no need to handle here */ @@ -676,6 +685,8 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } pthread_mutex_unlock(&LOCK_event_metadata); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(ret); } diff --git a/sql/sp.cc b/sql/sp.cc index 6fad1d70ffd..ff76dbf7921 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -896,6 +896,8 @@ sp_create_routine(THD *thd, int type, sp_head *sp) bool store_failed= FALSE; + bool save_binlog_row_based; + DBUG_ENTER("sp_create_routine"); DBUG_PRINT("enter", ("type: %d name: %.*s",type, (int) sp->m_name.length, sp->m_name.str)); @@ -913,6 +915,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->current_stmt_binlog_row_based; thd->clear_current_stmt_binlog_row_based(); saved_count_cuted_fields= thd->count_cuted_fields; @@ -1118,6 +1121,8 @@ done: thd->variables.sql_mode= saved_mode; close_thread_tables(thd); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(ret); } @@ -1142,6 +1147,7 @@ sp_drop_routine(THD *thd, int type, sp_name *name) { TABLE *table; int ret; + bool save_binlog_row_based; DBUG_ENTER("sp_drop_routine"); DBUG_PRINT("enter", ("type: %d name: %.*s", type, (int) name->m_name.length, name->m_name.str)); @@ -1154,6 +1160,7 @@ sp_drop_routine(THD *thd, int type, sp_name *name) row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->current_stmt_binlog_row_based; thd->clear_current_stmt_binlog_row_based(); if (!(table= open_proc_table_for_update(thd))) @@ -1171,6 +1178,8 @@ sp_drop_routine(THD *thd, int type, sp_name *name) } close_thread_tables(thd); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(ret); } @@ -1197,6 +1206,7 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) { TABLE *table; int ret; + bool save_binlog_row_based; DBUG_ENTER("sp_update_routine"); DBUG_PRINT("enter", ("type: %d name: %.*s", type, (int) name->m_name.length, name->m_name.str)); @@ -1208,6 +1218,7 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->current_stmt_binlog_row_based; thd->clear_current_stmt_binlog_row_based(); if (!(table= open_proc_table_for_update(thd))) @@ -1241,6 +1252,8 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) } close_thread_tables(thd); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(ret); } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 7ba1a657578..e2c47957e4d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2978,6 +2978,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, TABLE_LIST tables[3]; bool create_new_users=0; char *db_name, *table_name; + bool save_binlog_row_based; DBUG_ENTER("mysql_table_grant"); if (!initialized) @@ -3073,6 +3074,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->current_stmt_binlog_row_based; thd->clear_current_stmt_binlog_row_based(); #ifdef HAVE_REPLICATION @@ -3088,7 +3090,11 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, */ tables[0].updating= tables[1].updating= tables[2].updating= 1; if (!(thd->spcont || rpl_filter->tables_ok(0, tables))) + { + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(FALSE); + } } #endif @@ -3101,6 +3107,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, if (simple_open_n_lock_tables(thd,tables)) { // Should never happen close_thread_tables(thd); /* purecov: deadcode */ + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(TRUE); /* purecov: deadcode */ } @@ -3227,6 +3235,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, /* Tables are automatically closed */ thd->lex->restore_backup_query_tables_list(&backup); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(result); } @@ -3255,6 +3265,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, TABLE_LIST tables[2]; bool create_new_users=0, result=0; char *db_name, *table_name; + bool save_binlog_row_based; DBUG_ENTER("mysql_routine_grant"); if (!initialized) @@ -3290,6 +3301,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->current_stmt_binlog_row_based; thd->clear_current_stmt_binlog_row_based(); #ifdef HAVE_REPLICATION @@ -3305,13 +3317,19 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, */ tables[0].updating= tables[1].updating= 1; if (!(thd->spcont || rpl_filter->tables_ok(0, tables))) + { + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(FALSE); + } } #endif if (simple_open_n_lock_tables(thd,tables)) { // Should never happen close_thread_tables(thd); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(TRUE); } @@ -3387,6 +3405,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, } rw_unlock(&LOCK_grant); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; /* Tables are automatically closed */ DBUG_RETURN(result); @@ -3401,6 +3421,7 @@ bool mysql_grant(THD *thd, const char *db, List &list, char tmp_db[NAME_LEN+1]; bool create_new_users=0; TABLE_LIST tables[2]; + bool save_binlog_row_based; DBUG_ENTER("mysql_grant"); if (!initialized) { @@ -3429,6 +3450,7 @@ bool mysql_grant(THD *thd, const char *db, List &list, row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->current_stmt_binlog_row_based; thd->clear_current_stmt_binlog_row_based(); #ifdef HAVE_REPLICATION @@ -3444,13 +3466,19 @@ bool mysql_grant(THD *thd, const char *db, List &list, */ tables[0].updating= tables[1].updating= 1; if (!(thd->spcont || rpl_filter->tables_ok(0, tables))) + { + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(FALSE); + } } #endif if (simple_open_n_lock_tables(thd,tables)) { // This should never happen close_thread_tables(thd); /* purecov: deadcode */ + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(TRUE); /* purecov: deadcode */ } @@ -3510,6 +3538,8 @@ bool mysql_grant(THD *thd, const char *db, List &list, if (!result) my_ok(thd); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(result); } @@ -5666,6 +5696,7 @@ bool mysql_create_user(THD *thd, List &list) List_iterator user_list(list); TABLE_LIST tables[GRANT_TABLES]; bool some_users_created= FALSE; + bool save_binlog_row_based; DBUG_ENTER("mysql_create_user"); /* @@ -5673,11 +5704,16 @@ bool mysql_create_user(THD *thd, List &list) row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->current_stmt_binlog_row_based; thd->clear_current_stmt_binlog_row_based(); /* CREATE USER may be skipped on replication client. */ if ((result= open_grant_tables(thd, tables))) + { + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(result != 1); + } rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -5720,6 +5756,8 @@ bool mysql_create_user(THD *thd, List &list) rw_unlock(&LOCK_grant); close_thread_tables(thd); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(result); } @@ -5746,6 +5784,7 @@ bool mysql_drop_user(THD *thd, List &list) TABLE_LIST tables[GRANT_TABLES]; bool some_users_deleted= FALSE; ulong old_sql_mode= thd->variables.sql_mode; + bool save_binlog_row_based; DBUG_ENTER("mysql_drop_user"); /* @@ -5753,11 +5792,16 @@ bool mysql_drop_user(THD *thd, List &list) row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->current_stmt_binlog_row_based; thd->clear_current_stmt_binlog_row_based(); /* DROP USER may be skipped on replication client. */ if ((result= open_grant_tables(thd, tables))) + { + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(result != 1); + } thd->variables.sql_mode&= ~MODE_PAD_CHAR_TO_FULL_LENGTH; @@ -5794,6 +5838,8 @@ bool mysql_drop_user(THD *thd, List &list) rw_unlock(&LOCK_grant); close_thread_tables(thd); thd->variables.sql_mode= old_sql_mode; + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(result); } @@ -5820,6 +5866,7 @@ bool mysql_rename_user(THD *thd, List &list) List_iterator user_list(list); TABLE_LIST tables[GRANT_TABLES]; bool some_users_renamed= FALSE; + bool save_binlog_row_based; DBUG_ENTER("mysql_rename_user"); /* @@ -5827,11 +5874,16 @@ bool mysql_rename_user(THD *thd, List &list) row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->current_stmt_binlog_row_based; thd->clear_current_stmt_binlog_row_based(); /* RENAME USER may be skipped on replication client. */ if ((result= open_grant_tables(thd, tables))) + { + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(result != 1); + } rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -5878,6 +5930,8 @@ bool mysql_rename_user(THD *thd, List &list) rw_unlock(&LOCK_grant); close_thread_tables(thd); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(result); } @@ -5902,6 +5956,7 @@ bool mysql_revoke_all(THD *thd, List &list) int result; ACL_DB *acl_db; TABLE_LIST tables[GRANT_TABLES]; + bool save_binlog_row_based; DBUG_ENTER("mysql_revoke_all"); /* @@ -5909,10 +5964,15 @@ bool mysql_revoke_all(THD *thd, List &list) row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->current_stmt_binlog_row_based; thd->clear_current_stmt_binlog_row_based(); if ((result= open_grant_tables(thd, tables))) + { + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(result != 1); + } rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -6063,6 +6123,8 @@ bool mysql_revoke_all(THD *thd, List &list) if (result) my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0)); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(result); } @@ -6146,6 +6208,7 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, TABLE_LIST tables[GRANT_TABLES]; HASH *hash= is_proc ? &proc_priv_hash : &func_priv_hash; Silence_routine_definer_errors error_handler; + bool save_binlog_row_based; DBUG_ENTER("sp_revoke_privileges"); if ((result= open_grant_tables(thd, tables))) @@ -6162,6 +6225,7 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, row-based replication. The flag will be reset at the end of the statement. */ + save_binlog_row_based= thd->current_stmt_binlog_row_based; thd->clear_current_stmt_binlog_row_based(); /* Remove procedure access */ @@ -6198,6 +6262,8 @@ bool sp_revoke_privileges(THD *thd, const char *sp_db, const char *sp_name, close_thread_tables(thd); thd->pop_internal_handler(); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(error_handler.has_errors()); } diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index c6b41b59a3f..76cadc79c6f 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -398,6 +398,7 @@ int mysql_create_function(THD *thd,udf_func *udf) TABLE *table; TABLE_LIST tables; udf_func *u_d; + bool save_binlog_row_based; DBUG_ENTER("mysql_create_function"); if (!initialized) @@ -437,8 +438,8 @@ int mysql_create_function(THD *thd,udf_func *udf) Turn off row binlogging of this statement and use statement-based so that all supporting tables are updated for CREATE FUNCTION command. */ - if (thd->current_stmt_binlog_row_based) - thd->clear_current_stmt_binlog_row_based(); + save_binlog_row_based= thd->current_stmt_binlog_row_based; + thd->clear_current_stmt_binlog_row_based(); rw_wrlock(&THR_LOCK_udf); if ((hash_search(&udf_hash,(uchar*) udf->name.str, udf->name.length))) @@ -508,12 +509,16 @@ int mysql_create_function(THD *thd,udf_func *udf) /* Binlog the create function. */ write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(0); err: if (new_dl) dlclose(dl); rw_unlock(&THR_LOCK_udf); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(1); } @@ -525,6 +530,7 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) udf_func *udf; char *exact_name_str; uint exact_name_len; + bool save_binlog_row_based; DBUG_ENTER("mysql_drop_function"); if (!initialized) @@ -540,8 +546,8 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) Turn off row binlogging of this statement and use statement-based so that all supporting tables are updated for DROP FUNCTION command. */ - if (thd->current_stmt_binlog_row_based) - thd->clear_current_stmt_binlog_row_based(); + save_binlog_row_based= thd->current_stmt_binlog_row_based; + thd->clear_current_stmt_binlog_row_based(); rw_wrlock(&THR_LOCK_udf); if (!(udf=(udf_func*) hash_search(&udf_hash,(uchar*) udf_name->str, @@ -583,9 +589,13 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) /* Binlog the drop function. */ write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(0); err: rw_unlock(&THR_LOCK_udf); + /* Restore the state of binlog format */ + thd->current_stmt_binlog_row_based= save_binlog_row_based; DBUG_RETURN(1); } From f65b3f7889b48c8f9dea4c066093e0f7b99fde3f Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 22 Jan 2010 13:55:50 +0400 Subject: [PATCH 125/157] Applying InnoDB snapshot, fixes BUG#49238. Detailed revision comments: r6421 | jyang | 2010-01-12 07:59:16 +0200 (Tue, 12 Jan 2010) | 8 lines branches/5.1: Fix bug #49238: Creating/Dropping a temporary table while at 1023 transactions will cause assert. Handle possible DB_TOO_MANY_CONCURRENT_TRXS when deleting metadata in row_drop_table_for_mysql(). rb://220, approved by Marko --- storage/innobase/row/row0mysql.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 4fcb1fbf9f2..f7156403247 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -3245,19 +3245,13 @@ check_next_foreign: "END;\n" , FALSE, trx); - if (err != DB_SUCCESS) { - ut_a(err == DB_OUT_OF_FILE_SPACE); - - err = DB_MUST_GET_MORE_FILE_SPACE; - - row_mysql_handle_errors(&err, trx, NULL, NULL); - - ut_error; - } else { + switch (err) { ibool is_path; const char* name_or_path; mem_heap_t* heap; + case DB_SUCCESS: + heap = mem_heap_create(200); /* Clone the name, in case it has been allocated @@ -3322,7 +3316,27 @@ check_next_foreign: } mem_heap_free(heap); + break; + + case DB_TOO_MANY_CONCURRENT_TRXS: + /* Cannot even find a free slot for the + the undo log. We can directly exit here + and return the DB_TOO_MANY_CONCURRENT_TRXS + error. */ + break; + + case DB_OUT_OF_FILE_SPACE: + err = DB_MUST_GET_MORE_FILE_SPACE; + + row_mysql_handle_errors(&err, trx, NULL, NULL); + + /* Fall through to raise error */ + + default: + /* No other possible error returns */ + ut_error; } + funct_exit: trx_commit_for_mysql(trx); From 9aaa3cc4dfdb5c33e5eb9418df2af7e46f440704 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 22 Jan 2010 13:56:32 +0400 Subject: [PATCH 126/157] Applying InnoDB snapshot Detailed revision comments: r6422 | marko | 2010-01-12 11:34:27 +0200 (Tue, 12 Jan 2010) | 3 lines branches/5.1: Non-functional change: Make innobase_get_int_col_max_value() a static function. It does not access any fields of class ha_innobase. --- storage/innobase/handler/ha_innodb.cc | 9 +++++---- storage/innobase/handler/ha_innodb.h | 1 - 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index a1b8c551845..aca8be74b07 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3652,11 +3652,12 @@ skip_field: /************************************************************************ Get the upper limit of the MySQL integral and floating-point type. */ - +static ulonglong -ha_innobase::innobase_get_int_col_max_value( -/*========================================*/ - const Field* field) +innobase_get_int_col_max_value( +/*===========================*/ + /* out: maximum allowed value for the field */ + const Field* field) /* in: MySQL field */ { ulonglong max_value = 0; diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 9ddb516c3dc..8251af20a44 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -80,7 +80,6 @@ class ha_innobase: public handler ulong innobase_update_autoinc(ulonglong auto_inc); ulong innobase_initialize_autoinc(); dict_index_t* innobase_get_index(uint keynr); - ulonglong innobase_get_int_col_max_value(const Field* field); /* Init values for the class: */ public: From 12665e79e4ddffb23e351e04271c72b4b752c78a Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 22 Jan 2010 13:57:02 +0400 Subject: [PATCH 127/157] Applying InnoDB snapshot, fixes BUG#46193. Detailed revision comments: r6424 | marko | 2010-01-12 12:22:19 +0200 (Tue, 12 Jan 2010) | 16 lines branches/5.1: In innobase_initialize_autoinc(), do not attempt to read the maximum auto-increment value from the table if innodb_force_recovery is set to at least 4, so that writes are disabled. (Bug #46193) innobase_get_int_col_max_value(): Move the function definition before ha_innobase::innobase_initialize_autoinc(), because that function now calls this function. ha_innobase::innobase_initialize_autoinc(): Change the return type to void. Do not attempt to read the maximum auto-increment value from the table if innodb_force_recovery is set to at least 4. Issue ER_AUTOINC_READ_FAILED to the client when the auto-increment value cannot be read. rb://144 by Sunny, revised by Marko --- storage/innobase/handler/ha_innodb.cc | 238 ++++++++++++++------------ storage/innobase/handler/ha_innodb.h | 2 +- 2 files changed, 134 insertions(+), 106 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index aca8be74b07..9b6c2cf9895 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2575,58 +2575,151 @@ normalize_table_name( #endif } +/************************************************************************ +Get the upper limit of the MySQL integral and floating-point type. */ +static +ulonglong +innobase_get_int_col_max_value( +/*===========================*/ + /* out: maximum allowed value for the field */ + const Field* field) /* in: MySQL field */ +{ + ulonglong max_value = 0; + + switch(field->key_type()) { + /* TINY */ + case HA_KEYTYPE_BINARY: + max_value = 0xFFULL; + break; + case HA_KEYTYPE_INT8: + max_value = 0x7FULL; + break; + /* SHORT */ + case HA_KEYTYPE_USHORT_INT: + max_value = 0xFFFFULL; + break; + case HA_KEYTYPE_SHORT_INT: + max_value = 0x7FFFULL; + break; + /* MEDIUM */ + case HA_KEYTYPE_UINT24: + max_value = 0xFFFFFFULL; + break; + case HA_KEYTYPE_INT24: + max_value = 0x7FFFFFULL; + break; + /* LONG */ + case HA_KEYTYPE_ULONG_INT: + max_value = 0xFFFFFFFFULL; + break; + case HA_KEYTYPE_LONG_INT: + max_value = 0x7FFFFFFFULL; + break; + /* BIG */ + case HA_KEYTYPE_ULONGLONG: + max_value = 0xFFFFFFFFFFFFFFFFULL; + break; + case HA_KEYTYPE_LONGLONG: + max_value = 0x7FFFFFFFFFFFFFFFULL; + break; + case HA_KEYTYPE_FLOAT: + /* We use the maximum as per IEEE754-2008 standard, 2^24 */ + max_value = 0x1000000ULL; + break; + case HA_KEYTYPE_DOUBLE: + /* We use the maximum as per IEEE754-2008 standard, 2^53 */ + max_value = 0x20000000000000ULL; + break; + default: + ut_error; + } + + return(max_value); +} + /************************************************************************ Set the autoinc column max value. This should only be called once from ha_innobase::open(). Therefore there's no need for a covering lock. */ -ulong +void ha_innobase::innobase_initialize_autoinc() /*======================================*/ { - dict_index_t* index; ulonglong auto_inc; - const char* col_name; - ulint error = DB_SUCCESS; - dict_table_t* innodb_table = prebuilt->table; - - col_name = table->found_next_number_field->field_name; - index = innobase_get_index(table->s->next_number_index); - - /* Execute SELECT MAX(col_name) FROM TABLE; */ - error = row_search_max_autoinc(index, col_name, &auto_inc); - - if (error == DB_SUCCESS) { - - /* At the this stage we dont' know the increment - or the offset, so use default inrement of 1. */ - ++auto_inc; - - dict_table_autoinc_initialize(innodb_table, auto_inc); - - } else if (error == DB_RECORD_NOT_FOUND) { - ut_print_timestamp(stderr); - fprintf(stderr, " InnoDB: MySQL and InnoDB data " - "dictionaries are out of sync.\n" - "InnoDB: Unable to find the AUTOINC column %s in the " - "InnoDB table %s.\n" - "InnoDB: We set the next AUTOINC column value to the " - "maximum possible value,\n" - "InnoDB: in effect disabling the AUTOINC next value " - "generation.\n" - "InnoDB: You can either set the next AUTOINC value " - "explicitly using ALTER TABLE\n" - "InnoDB: or fix the data dictionary by recreating " - "the table.\n", - col_name, index->table->name); + const Field* field = table->found_next_number_field; + if (field != NULL) { + auto_inc = innobase_get_int_col_max_value(field); + } else { + /* We have no idea what's been passed in to us as the + autoinc column. We set it to the MAX_INT of our table + autoinc type. */ auto_inc = 0xFFFFFFFFFFFFFFFFULL; - dict_table_autoinc_initialize(innodb_table, auto_inc); + ut_print_timestamp(stderr); + fprintf(stderr, " InnoDB: Unable to determine the AUTOINC " + "column name\n"); + } - error = DB_SUCCESS; - } /* else other errors are still fatal */ + if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { + /* If the recovery level is set so high that writes + are disabled we force the AUTOINC counter to the MAX + value effectively disabling writes to the table. + Secondly, we avoid reading the table in case the read + results in failure due to a corrupted table/index. - return(ulong(error)); + We will not return an error to the client, so that the + tables can be dumped with minimal hassle. If an error + were returned in this case, the first attempt to read + the table would fail and subsequent SELECTs would succeed. */ + } else if (field == NULL) { + my_error(ER_AUTOINC_READ_FAILED, MYF(0)); + } else { + dict_index_t* index; + const char* col_name; + ulonglong read_auto_inc; + ulint err; + + update_thd(ha_thd()); + col_name = field->field_name; + index = innobase_get_index(table->s->next_number_index); + + /* Execute SELECT MAX(col_name) FROM TABLE; */ + err = row_search_max_autoinc(index, col_name, &read_auto_inc); + + switch (err) { + case DB_SUCCESS: + /* At the this stage we do not know the increment + or the offset, so use a default increment of 1. */ + auto_inc = read_auto_inc + 1; + break; + + case DB_RECORD_NOT_FOUND: + ut_print_timestamp(stderr); + fprintf(stderr, " InnoDB: MySQL and InnoDB data " + "dictionaries are out of sync.\n" + "InnoDB: Unable to find the AUTOINC column " + "%s in the InnoDB table %s.\n" + "InnoDB: We set the next AUTOINC column " + "value to the maximum possible value,\n" + "InnoDB: in effect disabling the AUTOINC " + "next value generation.\n" + "InnoDB: You can either set the next " + "AUTOINC value explicitly using ALTER TABLE\n" + "InnoDB: or fix the data dictionary by " + "recreating the table.\n", + col_name, index->table->name); + + my_error(ER_AUTOINC_READ_FAILED, MYF(0)); + break; + default: + /* row_search_max_autoinc() should only return + one of DB_SUCCESS or DB_RECORD_NOT_FOUND. */ + ut_error; + } + } + + dict_table_autoinc_initialize(prebuilt->table, auto_inc); } /********************************************************************* @@ -2824,8 +2917,6 @@ retry: /* Only if the table has an AUTOINC column. */ if (prebuilt->table != NULL && table->found_next_number_field != NULL) { - ulint error; - dict_table_autoinc_lock(prebuilt->table); /* Since a table can already be "open" in InnoDB's internal @@ -2834,8 +2925,7 @@ retry: autoinc value from a previous MySQL open. */ if (dict_table_autoinc_read(prebuilt->table) == 0) { - error = innobase_initialize_autoinc(); - ut_a(error == DB_SUCCESS); + innobase_initialize_autoinc(); } dict_table_autoinc_unlock(prebuilt->table); @@ -3650,68 +3740,6 @@ skip_field: } } -/************************************************************************ -Get the upper limit of the MySQL integral and floating-point type. */ -static -ulonglong -innobase_get_int_col_max_value( -/*===========================*/ - /* out: maximum allowed value for the field */ - const Field* field) /* in: MySQL field */ -{ - ulonglong max_value = 0; - - switch(field->key_type()) { - /* TINY */ - case HA_KEYTYPE_BINARY: - max_value = 0xFFULL; - break; - case HA_KEYTYPE_INT8: - max_value = 0x7FULL; - break; - /* SHORT */ - case HA_KEYTYPE_USHORT_INT: - max_value = 0xFFFFULL; - break; - case HA_KEYTYPE_SHORT_INT: - max_value = 0x7FFFULL; - break; - /* MEDIUM */ - case HA_KEYTYPE_UINT24: - max_value = 0xFFFFFFULL; - break; - case HA_KEYTYPE_INT24: - max_value = 0x7FFFFFULL; - break; - /* LONG */ - case HA_KEYTYPE_ULONG_INT: - max_value = 0xFFFFFFFFULL; - break; - case HA_KEYTYPE_LONG_INT: - max_value = 0x7FFFFFFFULL; - break; - /* BIG */ - case HA_KEYTYPE_ULONGLONG: - max_value = 0xFFFFFFFFFFFFFFFFULL; - break; - case HA_KEYTYPE_LONGLONG: - max_value = 0x7FFFFFFFFFFFFFFFULL; - break; - case HA_KEYTYPE_FLOAT: - /* We use the maximum as per IEEE754-2008 standard, 2^24 */ - max_value = 0x1000000ULL; - break; - case HA_KEYTYPE_DOUBLE: - /* We use the maximum as per IEEE754-2008 standard, 2^53 */ - max_value = 0x20000000000000ULL; - break; - default: - ut_error; - } - - return(max_value); -} - /************************************************************************ This special handling is really to overcome the limitations of MySQL's binlogging. We need to eliminate the non-determinism that will arise in diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 8251af20a44..5b3df16875a 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -78,7 +78,7 @@ class ha_innobase: public handler ulong innobase_reset_autoinc(ulonglong auto_inc); ulong innobase_get_autoinc(ulonglong* value); ulong innobase_update_autoinc(ulonglong auto_inc); - ulong innobase_initialize_autoinc(); + void innobase_initialize_autoinc(); dict_index_t* innobase_get_index(uint keynr); /* Init values for the class: */ From 407e6e309e0a32974e5db89da51b288242f1bb00 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 22 Jan 2010 14:02:17 +0400 Subject: [PATCH 128/157] Applying InnoDB snapshot Detailed revision comments: r6488 | sunny | 2010-01-21 02:55:08 +0200 (Thu, 21 Jan 2010) | 2 lines branches/5.1: Factor out test for bug#44030 from innodb-autoinc.test into a separate test/result files. --- mysql-test/r/innodb-autoinc.result | 29 ----------------------------- mysql-test/t/innodb-autoinc.test | 26 -------------------------- 2 files changed, 55 deletions(-) diff --git a/mysql-test/r/innodb-autoinc.result b/mysql-test/r/innodb-autoinc.result index fe87e11c9ec..c03daa3565e 100644 --- a/mysql-test/r/innodb-autoinc.result +++ b/mysql-test/r/innodb-autoinc.result @@ -868,35 +868,6 @@ Got one of the listed errors DROP TABLE t1; DROP TABLE t2; SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; -CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB; -INSERT INTO t1 VALUES (null); -INSERT INTO t1 VALUES (null); -ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT; -SELECT * FROM t1; -d1 -1 -2 -SELECT * FROM t1; -d1 -1 -2 -INSERT INTO t1 VALUES(null); -Got one of the listed errors -ALTER TABLE t1 AUTO_INCREMENT = 3; -SHOW CREATE TABLE t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `d1` int(11) NOT NULL AUTO_INCREMENT, - PRIMARY KEY (`d1`) -) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 -INSERT INTO t1 VALUES(null); -SELECT * FROM t1; -d1 -1 -2 -3 -DROP TABLE t1; -SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; SHOW VARIABLES LIKE "%auto_inc%"; Variable_name Value auto_increment_increment 1 diff --git a/mysql-test/t/innodb-autoinc.test b/mysql-test/t/innodb-autoinc.test index 84386280a26..bb431408937 100644 --- a/mysql-test/t/innodb-autoinc.test +++ b/mysql-test/t/innodb-autoinc.test @@ -478,32 +478,6 @@ INSERT INTO t2 SELECT c1 FROM t1; INSERT INTO t2 SELECT NULL FROM t1; DROP TABLE t1; DROP TABLE t2; -# -# 44030: Error: (1500) Couldn't read the MAX(ID) autoinc value from -# the index (PRIMARY) -# This test requires a restart of the server -SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; -CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB; -INSERT INTO t1 VALUES (null); -INSERT INTO t1 VALUES (null); -ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT; -SELECT * FROM t1; -# Restart the server --- source include/restart_mysqld.inc -# The MySQL and InnoDB data dictionaries should now be out of sync. -# The select should print message to the error log -SELECT * FROM t1; -# MySQL have made a change (http://lists.mysql.com/commits/75268) that no -# longer results in the two data dictionaries being out of sync. If they -# revert their changes then this check for ER_AUTOINC_READ_FAILED will need -# to be enabled. --- error ER_AUTOINC_READ_FAILED,1467 -INSERT INTO t1 VALUES(null); -ALTER TABLE t1 AUTO_INCREMENT = 3; -SHOW CREATE TABLE t1; -INSERT INTO t1 VALUES(null); -SELECT * FROM t1; -DROP TABLE t1; # If the user has specified negative values for an AUTOINC column then # InnoDB should ignore those values when setting the table's max value. From dab7c82fe5ce9152415354c8cac4c216ab49d4a6 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 22 Jan 2010 14:03:18 +0400 Subject: [PATCH 129/157] Applying InnoDB snapshot Detailed revision comments: r6489 | sunny | 2010-01-21 02:57:50 +0200 (Thu, 21 Jan 2010) | 2 lines branches/5.1: Factor out test for bug#44030 from innodb-autoinc.test into a separate test/result files. --- mysql-test/r/innodb-autoinc-44030.result | 30 +++++++++++++++++++++ mysql-test/t/innodb-autoinc-44030.test | 34 ++++++++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 mysql-test/r/innodb-autoinc-44030.result create mode 100644 mysql-test/t/innodb-autoinc-44030.test diff --git a/mysql-test/r/innodb-autoinc-44030.result b/mysql-test/r/innodb-autoinc-44030.result new file mode 100644 index 00000000000..c0695bf0be0 --- /dev/null +++ b/mysql-test/r/innodb-autoinc-44030.result @@ -0,0 +1,30 @@ +drop table if exists t1; +SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (null); +INSERT INTO t1 VALUES (null); +ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT; +SELECT * FROM t1; +d1 +1 +2 +SELECT * FROM t1; +d1 +1 +2 +INSERT INTO t1 VALUES(null); +Got one of the listed errors +ALTER TABLE t1 AUTO_INCREMENT = 3; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `d1` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`d1`) +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 +INSERT INTO t1 VALUES(null); +SELECT * FROM t1; +d1 +1 +2 +3 +DROP TABLE t1; diff --git a/mysql-test/t/innodb-autoinc-44030.test b/mysql-test/t/innodb-autoinc-44030.test new file mode 100644 index 00000000000..1dfdad2bede --- /dev/null +++ b/mysql-test/t/innodb-autoinc-44030.test @@ -0,0 +1,34 @@ +-- source include/have_innodb.inc +# embedded server ignores 'delayed', so skip this +-- source include/not_embedded.inc + +--disable_warnings +drop table if exists t1; +--enable_warnings + +# +# 44030: Error: (1500) Couldn't read the MAX(ID) autoinc value from +# the index (PRIMARY) +# This test requires a restart of the server +SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1; +CREATE TABLE t1 (c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB; +INSERT INTO t1 VALUES (null); +INSERT INTO t1 VALUES (null); +ALTER TABLE t1 CHANGE c1 d1 INT NOT NULL AUTO_INCREMENT; +SELECT * FROM t1; +# Restart the server +-- source include/restart_mysqld.inc +# The MySQL and InnoDB data dictionaries should now be out of sync. +# The select should print message to the error log +SELECT * FROM t1; +# MySQL have made a change (http://lists.mysql.com/commits/75268) that no +# longer results in the two data dictionaries being out of sync. If they +# revert their changes then this check for ER_AUTOINC_READ_FAILED will need +# to be enabled. +-- error ER_AUTOINC_READ_FAILED,1467 +INSERT INTO t1 VALUES(null); +ALTER TABLE t1 AUTO_INCREMENT = 3; +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES(null); +SELECT * FROM t1; +DROP TABLE t1; From b6a739f6d77886b7b3b32de857a7f89ff17984e3 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 22 Jan 2010 14:03:52 +0400 Subject: [PATCH 130/157] Applying InnoDB snapshot Detailed revision comments: r6492 | sunny | 2010-01-21 09:38:35 +0200 (Thu, 21 Jan 2010) | 1 line branches/5.1: Add reference to bug#47621 in the comment. --- mysql-test/t/innodb-autoinc-44030.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/innodb-autoinc-44030.test b/mysql-test/t/innodb-autoinc-44030.test index 1dfdad2bede..af2e3015280 100644 --- a/mysql-test/t/innodb-autoinc-44030.test +++ b/mysql-test/t/innodb-autoinc-44030.test @@ -24,7 +24,7 @@ SELECT * FROM t1; # MySQL have made a change (http://lists.mysql.com/commits/75268) that no # longer results in the two data dictionaries being out of sync. If they # revert their changes then this check for ER_AUTOINC_READ_FAILED will need -# to be enabled. +# to be enabled. Also, see http://bugs.mysql.com/bug.php?id=47621. -- error ER_AUTOINC_READ_FAILED,1467 INSERT INTO t1 VALUES(null); ALTER TABLE t1 AUTO_INCREMENT = 3; From f996e36de9c6f79816057e246b34ad9cc0ff1b76 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 22 Jan 2010 14:20:08 +0400 Subject: [PATCH 131/157] Disabled innodb-autoinc-44030 due to BUG#47621. --- 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 07462e91696..5f37dbe2cb6 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -11,3 +11,4 @@ ############################################################################## kill : Bug#37780 2008-12-03 HHunger need some changes to be robust enough for pushbuild. query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically +innodb-autoinc-44030 : BUG#47621 2009-01-22 svoj MySQL and InnoDB dicts getting out of sync From 4a10f7b46c9ebbd9af89f37f64df40981459b788 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Fri, 22 Jan 2010 14:58:21 +0400 Subject: [PATCH 132/157] Bug#49501 Inefficient information_schema check (system collation), addon removed wrongly introduced strlen calls sql/events.cc: removed wrongly introduced strlen calls sql/mysql_priv.h: removed wrongly introduced strlen calls sql/repl_failsafe.cc: removed wrongly introduced strlen calls sql/sql_db.cc: removed wrongly introduced strlen calls sql/sql_parse.cc: removed wrongly introduced strlen calls sql/sql_show.cc: removed wrongly introduced strlen calls --- sql/events.cc | 3 +-- sql/mysql_priv.h | 6 ++++++ sql/repl_failsafe.cc | 2 +- sql/sql_db.cc | 2 +- sql/sql_parse.cc | 6 +++--- sql/sql_show.cc | 2 +- 6 files changed, 13 insertions(+), 8 deletions(-) diff --git a/sql/events.cc b/sql/events.cc index 790e6a61699..3273635666e 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -871,8 +871,7 @@ Events::fill_schema_events(THD *thd, TABLE_LIST *tables, COND * /* cond */) if (thd->lex->sql_command == SQLCOM_SHOW_EVENTS) { DBUG_ASSERT(thd->lex->select_lex.db); - if (!is_schema_db(thd->lex->select_lex.db, // There is no events in I_S - strlen(thd->lex->select_lex.db)) && + if (!is_schema_db(thd->lex->select_lex.db) && // There is no events in I_S check_access(thd, EVENT_ACL, thd->lex->select_lex.db, 0, 0, 0, 0)) DBUG_RETURN(1); db= thd->lex->select_lex.db; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 76edbf1dea3..abc50cd8063 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1426,6 +1426,12 @@ inline bool is_schema_db(const char *name, size_t len) INFORMATION_SCHEMA_NAME.str, name)); } +inline bool is_schema_db(const char *name) +{ + return !my_strcasecmp(system_charset_info, + INFORMATION_SCHEMA_NAME.str, name); +} + /* sql_prepare.cc */ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length); diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index dda84ca8a37..c6a05e93bf4 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -905,7 +905,7 @@ bool load_master_data(THD* thd) if (!rpl_filter->db_ok(db) || !rpl_filter->db_ok_with_wild_table(db) || !strcmp(db,"mysql") || - is_schema_db(db, strlen(db))) + is_schema_db(db)) { *cur_table_res = 0; continue; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 22ecaa17a0c..a3f9b4baea4 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -618,7 +618,7 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, DBUG_ENTER("mysql_create_db"); /* do not create 'information_schema' db */ - if (is_schema_db(db, strlen(db))) + if (is_schema_db(db)) { my_error(ER_DB_CREATE_EXISTS, MYF(0), db); DBUG_RETURN(-1); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3c404a984bf..a2a1494141c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2852,7 +2852,7 @@ end_with_restore_list: &first_table->grant.privilege, 0, 0, test(first_table->schema_table)) || check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0, - is_schema_db(select_lex->db, strlen(select_lex->db)))|| + is_schema_db(select_lex->db))|| check_merge_table_access(thd, first_table->db, (TABLE_LIST *) create_info.merge_list.first)) @@ -3865,7 +3865,7 @@ end_with_restore_list: first_table ? 0 : 1, 0, first_table ? (bool) first_table->schema_table : select_lex->db ? - is_schema_db(select_lex->db, strlen(select_lex->db)) : 0)) + is_schema_db(select_lex->db) : 0)) goto error; if (thd->security_ctx->user) // If not replication @@ -5304,7 +5304,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table) if (check_access(thd, SELECT_ACL, dst_db_name, &thd->col_access, FALSE, FALSE, - is_schema_db(dst_db_name, strlen(dst_db_name)))) + is_schema_db(dst_db_name))) return TRUE; if (!thd->col_access && check_grant_db(thd, dst_db_name)) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index d4da29085b5..5ec40d4893c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -826,7 +826,7 @@ bool mysqld_show_create_db(THD *thd, char *dbname, DBUG_RETURN(TRUE); } #endif - if (is_schema_db(dbname, strlen(dbname))) + if (is_schema_db(dbname)) { dbname= INFORMATION_SCHEMA_NAME.str; create.default_table_charset= system_charset_info; From d93550cb80deb587843940a0102b18473aae2f5d Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Fri, 22 Jan 2010 16:23:27 +0400 Subject: [PATCH 133/157] Applying InnoDB snapshot, fixes BUG#49396. Detailed revision comments: r6471 | calvin | 2010-01-16 01:43:27 +0200 (Sat, 16 Jan 2010) | 4 lines branches/5.1: fix bug#49396: main.innodb test fails in embedded mode Change replace_result by using $MYSQLD_DATADIR. Tested in both embedded mode and normal server mode. --- mysql-test/t/innodb.test | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 42c24324ebc..8dcf494406a 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -15,6 +15,8 @@ -- source include/have_innodb.inc +let $MYSQLD_DATADIR= `select @@datadir`; + # Save the original values of some variables in order to be able to # estimate how much they have changed during the tests. Previously this # test assumed that e.g. rows_deleted is 0 here and after deleting 23 @@ -1699,7 +1701,7 @@ set foreign_key_checks=0; create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1; create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8; # Embedded server doesn't chdir to data directory ---replace_result $MYSQLTEST_VARDIR . mysqld.1/data/ '' +--replace_result $MYSQLD_DATADIR ./ master-data/ '' -- error 1025 rename table t3 to t1; set foreign_key_checks=1; @@ -2339,7 +2341,7 @@ ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1 (a) ON DELETE SET NULL; # mysqltest first does replace_regex, then replace_result --replace_regex /'[^']*test\/#sql-[0-9a-f_]*'/'#sql-temporary'/ # Embedded server doesn't chdir to data directory ---replace_result $MYSQLTEST_VARDIR . mysqld.1/data/ '' +--replace_result $MYSQLD_DATADIR ./ master-data/ '' --error 1025 ALTER TABLE t2 MODIFY a INT NOT NULL; DELETE FROM t1; From 2b16517522afad76bc94b07bdaa8af64091e713b Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Sun, 24 Jan 2010 15:03:23 +0800 Subject: [PATCH 134/157] Backport Bug#37148 to 5.1 --- mysql-test/include/binlog_inject_error.inc | 22 ++++ .../suite/binlog/r/binlog_write_error.result | 108 ++++++++++++++++++ .../suite/binlog/t/binlog_write_error.test | 101 ++++++++++++++++ sql/events.cc | 6 +- sql/log.cc | 4 +- sql/log_event.cc | 6 +- sql/log_event_old.cc | 15 ++- sql/mysql_priv.h | 4 +- sql/rpl_injector.cc | 41 ++++--- sql/sp.cc | 13 ++- sql/sp_head.cc | 1 + sql/sql_acl.cc | 25 ++-- sql/sql_base.cc | 18 ++- sql/sql_class.h | 2 +- sql/sql_db.cc | 35 ++++-- sql/sql_delete.cc | 12 +- sql/sql_insert.cc | 51 +++++---- sql/sql_load.cc | 32 +++--- sql/sql_parse.cc | 17 +-- sql/sql_partition.cc | 5 +- sql/sql_rename.cc | 9 +- sql/sql_repl.cc | 13 ++- sql/sql_table.cc | 62 +++++----- sql/sql_tablespace.cc | 4 +- sql/sql_trigger.cc | 2 +- sql/sql_udf.cc | 8 +- sql/sql_update.cc | 7 +- sql/sql_view.cc | 8 +- 28 files changed, 472 insertions(+), 159 deletions(-) create mode 100644 mysql-test/include/binlog_inject_error.inc create mode 100644 mysql-test/suite/binlog/r/binlog_write_error.result create mode 100644 mysql-test/suite/binlog/t/binlog_write_error.test diff --git a/mysql-test/include/binlog_inject_error.inc b/mysql-test/include/binlog_inject_error.inc new file mode 100644 index 00000000000..6465f7943a4 --- /dev/null +++ b/mysql-test/include/binlog_inject_error.inc @@ -0,0 +1,22 @@ +# +# === Name +# +# binlog_inject_error.inc +# +# === Description +# +# Inject binlog write error when running the query, verifies that the +# query is ended with the proper error (ER_ERROR_ON_WRITE). +# +# === Usage +# +# let query= 'CREATE TABLE t1 (a INT)'; +# source include/binlog_inject_error.inc; +# + +SET GLOBAL debug='d,injecting_fault_writing'; +--echo $query; +--replace_regex /(errno: .*)/(errno: #)/ +--error ER_ERROR_ON_WRITE +--eval $query +SET GLOBAL debug=''; diff --git a/mysql-test/suite/binlog/r/binlog_write_error.result b/mysql-test/suite/binlog/r/binlog_write_error.result new file mode 100644 index 00000000000..dd8bdb9715a --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_write_error.result @@ -0,0 +1,108 @@ +# +# Initialization +# +DROP TABLE IF EXISTS t1, t2; +DROP FUNCTION IF EXISTS f1; +DROP FUNCTION IF EXISTS f2; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; +DROP TRIGGER IF EXISTS tr1; +DROP TRIGGER IF EXISTS tr2; +DROP VIEW IF EXISTS v1, v2; +# +# Test injecting binlog write error when executing queries +# +SET GLOBAL debug='d,injecting_fault_writing'; +CREATE TABLE t1 (a INT); +CREATE TABLE t1 (a INT); +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +INSERT INTO t1 VALUES (1),(2),(3); +SET GLOBAL debug='d,injecting_fault_writing'; +INSERT INTO t1 VALUES (4),(5),(6); +INSERT INTO t1 VALUES (4),(5),(6); +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +SET GLOBAL debug='d,injecting_fault_writing'; +UPDATE t1 set a=a+1; +UPDATE t1 set a=a+1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +SET GLOBAL debug='d,injecting_fault_writing'; +DELETE FROM t1; +DELETE FROM t1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +SET GLOBAL debug='d,injecting_fault_writing'; +CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100); +CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100); +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +SET GLOBAL debug='d,injecting_fault_writing'; +DROP TRIGGER tr1; +DROP TRIGGER tr1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +SET GLOBAL debug='d,injecting_fault_writing'; +ALTER TABLE t1 ADD (b INT); +ALTER TABLE t1 ADD (b INT); +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +SET GLOBAL debug='d,injecting_fault_writing'; +CREATE VIEW v1 AS SELECT a FROM t1; +CREATE VIEW v1 AS SELECT a FROM t1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +SET GLOBAL debug='d,injecting_fault_writing'; +DROP VIEW v1; +DROP VIEW v1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +SET GLOBAL debug='d,injecting_fault_writing'; +CREATE PROCEDURE p1(OUT rows INT) SELECT count(*) INTO rows FROM t1; +CREATE PROCEDURE p1(OUT rows INT) SELECT count(*) INTO rows FROM t1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +SET GLOBAL debug='d,injecting_fault_writing'; +DROP PROCEDURE p1; +DROP PROCEDURE p1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +SET GLOBAL debug='d,injecting_fault_writing'; +DROP TABLE t1; +DROP TABLE t1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +SET GLOBAL debug='d,injecting_fault_writing'; +CREATE FUNCTION f1() RETURNS INT return 1; +CREATE FUNCTION f1() RETURNS INT return 1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +SET GLOBAL debug='d,injecting_fault_writing'; +DROP FUNCTION f1; +DROP FUNCTION f1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +SET GLOBAL debug='d,injecting_fault_writing'; +CREATE USER user1; +CREATE USER user1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +SET GLOBAL debug='d,injecting_fault_writing'; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1; +REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +SET GLOBAL debug='d,injecting_fault_writing'; +DROP USER user1; +DROP USER user1; +ERROR HY000: Error writing file 'master-bin' ((errno: #) +SET GLOBAL debug=''; +# +# Cleanup +# +DROP TABLE IF EXISTS t1, t2; +DROP FUNCTION IF EXISTS f1; +DROP PROCEDURE IF EXISTS p1; +DROP TRIGGER IF EXISTS tr1; +DROP VIEW IF EXISTS v1, v2; diff --git a/mysql-test/suite/binlog/t/binlog_write_error.test b/mysql-test/suite/binlog/t/binlog_write_error.test new file mode 100644 index 00000000000..0e57db3d9a0 --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_write_error.test @@ -0,0 +1,101 @@ +# +# === Name === +# +# binlog_write_error.test +# +# === Description === +# +# This test case check if the error of writing binlog file is properly +# reported and handled when executing statements. +# +# === Related Bugs === +# +# BUG#37148 +# + +source include/have_log_bin.inc; +source include/have_debug.inc; + +--echo # +--echo # Initialization +--echo # + +disable_warnings; +DROP TABLE IF EXISTS t1, t2; +DROP FUNCTION IF EXISTS f1; +DROP FUNCTION IF EXISTS f2; +DROP PROCEDURE IF EXISTS p1; +DROP PROCEDURE IF EXISTS p2; +DROP TRIGGER IF EXISTS tr1; +DROP TRIGGER IF EXISTS tr2; +DROP VIEW IF EXISTS v1, v2; +enable_warnings; + +--echo # +--echo # Test injecting binlog write error when executing queries +--echo # + +let $query= CREATE TABLE t1 (a INT); +source include/binlog_inject_error.inc; + +INSERT INTO t1 VALUES (1),(2),(3); + +let $query= INSERT INTO t1 VALUES (4),(5),(6); +source include/binlog_inject_error.inc; + +let $query= UPDATE t1 set a=a+1; +source include/binlog_inject_error.inc; + +let $query= DELETE FROM t1; +source include/binlog_inject_error.inc; + +let $query= CREATE TRIGGER tr1 AFTER INSERT ON t1 FOR EACH ROW INSERT INTO t1 VALUES (new.a + 100); +source include/binlog_inject_error.inc; + +let $query= DROP TRIGGER tr1; +source include/binlog_inject_error.inc; + +let $query= ALTER TABLE t1 ADD (b INT); +source include/binlog_inject_error.inc; + +let $query= CREATE VIEW v1 AS SELECT a FROM t1; +source include/binlog_inject_error.inc; + +let $query= DROP VIEW v1; +source include/binlog_inject_error.inc; + +let $query= CREATE PROCEDURE p1(OUT rows INT) SELECT count(*) INTO rows FROM t1; +source include/binlog_inject_error.inc; + +let $query= DROP PROCEDURE p1; +source include/binlog_inject_error.inc; + +let $query= DROP TABLE t1; +source include/binlog_inject_error.inc; + +let $query= CREATE FUNCTION f1() RETURNS INT return 1; +source include/binlog_inject_error.inc; + +let $query= DROP FUNCTION f1; +source include/binlog_inject_error.inc; + +let $query= CREATE USER user1; +source include/binlog_inject_error.inc; + +let $query= REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1; +source include/binlog_inject_error.inc; + +let $query= DROP USER user1; +source include/binlog_inject_error.inc; + +--echo # +--echo # Cleanup +--echo # + +disable_warnings; +DROP TABLE IF EXISTS t1, t2; +DROP FUNCTION IF EXISTS f1; +DROP PROCEDURE IF EXISTS p1; +DROP TRIGGER IF EXISTS tr1; +DROP VIEW IF EXISTS v1, v2; +enable_warnings; diff --git a/sql/events.cc b/sql/events.cc index 3273635666e..2770cabae19 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -476,7 +476,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, } /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER will be written into the binary log as the definer for the SQL thread. */ - write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length()); + ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length()); } } pthread_mutex_unlock(&LOCK_event_metadata); @@ -598,7 +598,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, new_element); /* Binlog the alter event. */ DBUG_ASSERT(thd->query() && thd->query_length()); - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } } pthread_mutex_unlock(&LOCK_event_metadata); @@ -673,7 +673,7 @@ Events::drop_event(THD *thd, LEX_STRING dbname, LEX_STRING name, bool if_exists) event_queue->drop_event(thd, dbname, name); /* Binlog the drop event. */ DBUG_ASSERT(thd->query() && thd->query_length()); - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } pthread_mutex_unlock(&LOCK_event_metadata); DBUG_RETURN(ret); diff --git a/sql/log.cc b/sql/log.cc index bc9efd75ea2..5544d0010ef 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1464,7 +1464,7 @@ binlog_end_trans(THD *thd, binlog_trx_data *trx_data, if (all || !(thd->options & (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT))) { if (trx_data->has_incident()) - mysql_bin_log.write_incident(thd, TRUE); + error= mysql_bin_log.write_incident(thd, TRUE); trx_data->reset(); } else // ...statement @@ -4710,7 +4710,7 @@ bool MYSQL_BIN_LOG::write_incident(THD *thd, bool lock) Incident_log_event ev(thd, incident, write_error_msg); if (lock) pthread_mutex_lock(&LOCK_log); - ev.write(&log_file); + error= ev.write(&log_file); if (lock) { if (!error && !(error= flush_and_sync())) diff --git a/sql/log_event.cc b/sql/log_event.cc index 6b21087b6aa..5219eae6600 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -5864,7 +5864,7 @@ Slave_log_event::Slave_log_event(const char* buf, uint event_len) int Slave_log_event::do_apply_event(Relay_log_info const *rli) { if (mysql_bin_log.is_open()) - mysql_bin_log.write(this); + return mysql_bin_log.write(this); return 0; } #endif /* !MYSQL_CLIENT */ @@ -7611,7 +7611,7 @@ static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD * thd) (assume the last master's transaction is ignored by the slave because of replicate-ignore rules). */ - thd->binlog_flush_pending_rows_event(true); + error= thd->binlog_flush_pending_rows_event(true); /* If this event is not in a transaction, the call below will, if some @@ -7622,7 +7622,7 @@ static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD * thd) are involved, commit the transaction and flush the pending event to the binlog. */ - error= ha_autocommit_or_rollback(thd, 0); + error|= ha_autocommit_or_rollback(thd, error); /* Now what if this is not a transactional engine? we still need to diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 357bc78b1cd..313916c9818 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -1541,7 +1541,15 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli) NOTE: For this new scheme there should be no pending event: need to add code to assert that is the case. */ - thd->binlog_flush_pending_rows_event(false); + error= thd->binlog_flush_pending_rows_event(false); + if (error) + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER(ER_SLAVE_FATAL_ERROR), + "call to binlog_flush_pending_rows_event() failed"); + thd->is_slave_error= 1; + DBUG_RETURN(error); + } TABLE_LIST *tables= rli->tables_to_lock; close_tables_for_reopen(thd, &tables); @@ -1831,7 +1839,7 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli) (assume the last master's transaction is ignored by the slave because of replicate-ignore rules). */ - thd->binlog_flush_pending_rows_event(true); + int binlog_error= thd->binlog_flush_pending_rows_event(true); /* If this event is not in a transaction, the call below will, if some @@ -1842,12 +1850,13 @@ int Old_rows_log_event::do_apply_event(Relay_log_info const *rli) are involved, commit the transaction and flush the pending event to the binlog. */ - if ((error= ha_autocommit_or_rollback(thd, 0))) + if ((error= ha_autocommit_or_rollback(thd, binlog_error))) rli->report(ERROR_LEVEL, error, "Error in %s event: commit of row events failed, " "table `%s`.`%s`", get_type_str(), m_table->s->db.str, m_table->s->table_name.str); + error|= binlog_error; /* Now what if this is not a transactional engine? we still need to diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index abc50cd8063..e99effe1dcb 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1036,8 +1036,8 @@ check_and_unset_inject_value(int value) #endif -void write_bin_log(THD *thd, bool clear_error, - char const *query, ulong query_length); +int write_bin_log(THD *thd, bool clear_error, + char const *query, ulong query_length); /* sql_connect.cc */ int check_user(THD *thd, enum enum_server_command command, diff --git a/sql/rpl_injector.cc b/sql/rpl_injector.cc index 684655d1c3b..666622dbac4 100644 --- a/sql/rpl_injector.cc +++ b/sql/rpl_injector.cc @@ -58,10 +58,14 @@ injector::transaction::~transaction() my_free(the_memory, MYF(0)); } +/** + @retval 0 transaction committed + @retval 1 transaction rolled back + */ int injector::transaction::commit() { DBUG_ENTER("injector::transaction::commit()"); - m_thd->binlog_flush_pending_rows_event(true); + int error= m_thd->binlog_flush_pending_rows_event(true); /* Cluster replication does not preserve statement or transaction boundaries of the master. Instead, a new @@ -81,9 +85,9 @@ int injector::transaction::commit() is committed by committing the statement transaction explicitly. */ - ha_autocommit_or_rollback(m_thd, 0); - end_trans(m_thd, COMMIT); - DBUG_RETURN(0); + error |= ha_autocommit_or_rollback(m_thd, error); + end_trans(m_thd, error ? ROLLBACK : COMMIT); + DBUG_RETURN(error); } int injector::transaction::use_table(server_id_type sid, table tbl) @@ -109,16 +113,17 @@ int injector::transaction::write_row (server_id_type sid, table tbl, record_type record) { DBUG_ENTER("injector::transaction::write_row(...)"); - - if (int error= check_state(ROW_STATE)) + + int error= 0; + if (error= check_state(ROW_STATE)) DBUG_RETURN(error); server_id_type save_id= m_thd->server_id; m_thd->set_server_id(sid); - m_thd->binlog_write_row(tbl.get_table(), tbl.is_transactional(), - cols, colcnt, record); + error= m_thd->binlog_write_row(tbl.get_table(), tbl.is_transactional(), + cols, colcnt, record); m_thd->set_server_id(save_id); - DBUG_RETURN(0); + DBUG_RETURN(error); } @@ -128,15 +133,16 @@ int injector::transaction::delete_row(server_id_type sid, table tbl, { DBUG_ENTER("injector::transaction::delete_row(...)"); - if (int error= check_state(ROW_STATE)) + int error= 0; + if (error= check_state(ROW_STATE)) DBUG_RETURN(error); server_id_type save_id= m_thd->server_id; m_thd->set_server_id(sid); - m_thd->binlog_delete_row(tbl.get_table(), tbl.is_transactional(), - cols, colcnt, record); + error= m_thd->binlog_delete_row(tbl.get_table(), tbl.is_transactional(), + cols, colcnt, record); m_thd->set_server_id(save_id); - DBUG_RETURN(0); + DBUG_RETURN(error); } @@ -146,15 +152,16 @@ int injector::transaction::update_row(server_id_type sid, table tbl, { DBUG_ENTER("injector::transaction::update_row(...)"); - if (int error= check_state(ROW_STATE)) + int error= 0; + if (error= check_state(ROW_STATE)) DBUG_RETURN(error); server_id_type save_id= m_thd->server_id; m_thd->set_server_id(sid); - m_thd->binlog_update_row(tbl.get_table(), tbl.is_transactional(), - cols, colcnt, before, after); + error= m_thd->binlog_update_row(tbl.get_table(), tbl.is_transactional(), + cols, colcnt, before, after); m_thd->set_server_id(save_id); - DBUG_RETURN(0); + DBUG_RETURN(error); } diff --git a/sql/sp.cc b/sql/sp.cc index 6fad1d70ffd..30896acd913 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1105,9 +1105,10 @@ sp_create_routine(THD *thd, int type, sp_head *sp) /* restore sql_mode when binloging */ thd->variables.sql_mode= saved_mode; /* Such a statement can always go directly to binlog, no trans cache */ - thd->binlog_query(THD::MYSQL_QUERY_TYPE, - log_query.c_ptr(), log_query.length(), - FALSE, FALSE, 0); + if (thd->binlog_query(THD::MYSQL_QUERY_TYPE, + log_query.c_ptr(), log_query.length(), + FALSE, FALSE, 0)) + ret= SP_INTERNAL_ERROR; thd->variables.sql_mode= 0; } @@ -1166,7 +1167,8 @@ sp_drop_routine(THD *thd, int type, sp_name *name) if (ret == SP_OK) { - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + if (write_bin_log(thd, TRUE, thd->query(), thd->query_length())) + ret= SP_INTERNAL_ERROR; sp_cache_invalidate(); } @@ -1236,7 +1238,8 @@ sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) if (ret == SP_OK) { - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + if (write_bin_log(thd, TRUE, thd->query(), thd->query_length())) + ret= SP_INTERNAL_ERROR; sp_cache_invalidate(); } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index d74e195048f..45cb4eebb09 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1790,6 +1790,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR, "Invoked ROUTINE modified a transactional table but MySQL " "failed to reflect this change in the binary log"); + err_status= TRUE; } reset_dynamic(&thd->user_var_events); /* Forget those values, in case more function calls are binlogged: */ diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 7ba1a657578..1fd70b4039e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1659,8 +1659,8 @@ bool change_password(THD *thd, const char *host, const char *user, acl_user->host.hostname ? acl_user->host.hostname : "", new_password)); thd->clear_error(); - thd->binlog_query(THD::MYSQL_QUERY_TYPE, buff, query_length, - FALSE, FALSE, 0); + result= thd->binlog_query(THD::MYSQL_QUERY_TYPE, buff, query_length, + FALSE, FALSE, 0); } end: close_thread_tables(thd); @@ -3217,7 +3217,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, if (!result) /* success */ { - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + result= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } rw_unlock(&LOCK_grant); @@ -3383,7 +3383,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, if (write_to_binlog) { - write_bin_log(thd, FALSE, thd->query(), thd->query_length()); + if (write_bin_log(thd, FALSE, thd->query(), thd->query_length())) + result= TRUE; } rw_unlock(&LOCK_grant); @@ -3502,7 +3503,7 @@ bool mysql_grant(THD *thd, const char *db, List &list, if (!result) { - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + result= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } rw_unlock(&LOCK_grant); @@ -5716,7 +5717,7 @@ bool mysql_create_user(THD *thd, List &list) my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr_safe()); if (some_users_created) - write_bin_log(thd, FALSE, thd->query(), thd->query_length()); + result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length()); rw_unlock(&LOCK_grant); close_thread_tables(thd); @@ -5789,7 +5790,7 @@ bool mysql_drop_user(THD *thd, List &list) my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe()); if (some_users_deleted) - write_bin_log(thd, FALSE, thd->query(), thd->query_length()); + result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length()); rw_unlock(&LOCK_grant); close_thread_tables(thd); @@ -5874,7 +5875,7 @@ bool mysql_rename_user(THD *thd, List &list) my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe()); if (some_users_renamed && mysql_bin_log.is_open()) - write_bin_log(thd, FALSE, thd->query(), thd->query_length()); + result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length()); rw_unlock(&LOCK_grant); close_thread_tables(thd); @@ -6056,15 +6057,17 @@ bool mysql_revoke_all(THD *thd, List &list) VOID(pthread_mutex_unlock(&acl_cache->lock)); - write_bin_log(thd, FALSE, thd->query(), thd->query_length()); + int binlog_error= + write_bin_log(thd, FALSE, thd->query(), thd->query_length()); rw_unlock(&LOCK_grant); close_thread_tables(thd); - if (result) + /* error for writing binary log has already been reported */ + if (result && !binlog_error) my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0)); - DBUG_RETURN(result); + DBUG_RETURN(result || binlog_error); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 9bb4ebedd55..a1f34f6a770 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1336,7 +1336,7 @@ void close_thread_tables(THD *thd) handled either before writing a query log event (inside binlog_query()) or when preparing a pending event. */ - thd->binlog_flush_pending_rows_event(TRUE); + (void)thd->binlog_flush_pending_rows_event(TRUE); mysql_unlock_tables(thd, thd->lock); thd->lock=0; } @@ -1550,7 +1550,11 @@ void close_temporary_tables(THD *thd) qinfo.db= db.ptr(); qinfo.db_len= db.length(); thd->variables.character_set_client= cs_save; - mysql_bin_log.write(&qinfo); + if (mysql_bin_log.write(&qinfo)) + { + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, MYF(0), + "Failed to write the DROP statement for temporary tables to binary log"); + } thd->variables.pseudo_thread_id= save_pseudo_thread_id; } else @@ -4031,9 +4035,13 @@ retry: end = strxmov(strmov(query, "DELETE FROM `"), share->db.str,"`.`",share->table_name.str,"`", NullS); int errcode= query_error_code(thd, TRUE); - thd->binlog_query(THD::STMT_QUERY_TYPE, - query, (ulong)(end-query), - FALSE, FALSE, errcode); + if (thd->binlog_query(THD::STMT_QUERY_TYPE, + query, (ulong)(end-query), + FALSE, FALSE, errcode)) + { + my_free(query, MYF(0)); + goto err; + } my_free(query, MYF(0)); } else diff --git a/sql/sql_class.h b/sql/sql_class.h index 56d31be79c7..77b4aa6c1d0 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2621,7 +2621,7 @@ public: {} int prepare(List &list, SELECT_LEX_UNIT *u); - void binlog_show_create_table(TABLE **tables, uint count); + int binlog_show_create_table(TABLE **tables, uint count); void store_values(List &values); void send_error(uint errcode,const char *err); bool send_eof(); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index a3f9b4baea4..d5d9830f63d 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -178,13 +178,13 @@ uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length, Helper function to write a query to binlog used by mysql_rm_db() */ -static inline void write_to_binlog(THD *thd, char *query, uint q_len, - char *db, uint db_len) +static inline int write_to_binlog(THD *thd, char *query, uint q_len, + char *db, uint db_len) { Query_log_event qinfo(thd, query, q_len, 0, 0, 0); qinfo.db= db; qinfo.db_len= db_len; - mysql_bin_log.write(&qinfo); + return mysql_bin_log.write(&qinfo); } @@ -747,7 +747,11 @@ not_silent: qinfo.db_len = strlen(db); /* These DDL methods and logging protected with LOCK_mysql_create_db */ - mysql_bin_log.write(&qinfo); + if (mysql_bin_log.write(&qinfo)) + { + error= -1; + goto exit; + } } my_ok(thd, result); } @@ -824,7 +828,8 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) qinfo.db_len = strlen(db); /* These DDL methods and logging protected with LOCK_mysql_create_db */ - mysql_bin_log.write(&qinfo); + if (error= mysql_bin_log.write(&qinfo)) + goto exit; } my_ok(thd, result); @@ -974,7 +979,11 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) qinfo.db_len = strlen(db); /* These DDL methods and logging protected with LOCK_mysql_create_db */ - mysql_bin_log.write(&qinfo); + if (mysql_bin_log.write(&qinfo)) + { + error= -1; + goto exit; + } } thd->clear_error(); thd->server_status|= SERVER_STATUS_DB_DROPPED; @@ -1002,7 +1011,11 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) if (query_pos + tbl_name_len + 1 >= query_end) { /* These DDL methods and logging protected with LOCK_mysql_create_db */ - write_to_binlog(thd, query, query_pos -1 - query, db, db_len); + if (write_to_binlog(thd, query, query_pos -1 - query, db, db_len)) + { + error= -1; + goto exit; + } query_pos= query_data_start; } @@ -1015,7 +1028,11 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) if (query_pos != query_data_start) { /* These DDL methods and logging protected with LOCK_mysql_create_db */ - write_to_binlog(thd, query, query_pos -1 - query, db, db_len); + if (write_to_binlog(thd, query, query_pos -1 - query, db, db_len)) + { + error= -1; + goto exit; + } } } @@ -1965,7 +1982,7 @@ bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db) Query_log_event qinfo(thd, thd->query(), thd->query_length(), 0, TRUE, errcode); thd->clear_error(); - mysql_bin_log.write(&qinfo); + error|= mysql_bin_log.write(&qinfo); } /* Step9: Let's do "use newdb" if we renamed the current database */ diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 6b9a83e695b..af3fdf11696 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -850,9 +850,10 @@ void multi_delete::abort() if (mysql_bin_log.is_open()) { int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); - thd->binlog_query(THD::ROW_QUERY_TYPE, - thd->query(), thd->query_length(), - transactional_tables, FALSE, errcode); + /* possible error of writing binary log is ignored deliberately */ + (void) thd->binlog_query(THD::ROW_QUERY_TYPE, + thd->query(), thd->query_length(), + transactional_tables, FALSE, errcode); } thd->transaction.all.modified_non_trans_table= true; } @@ -1167,8 +1168,9 @@ end: { /* In RBR, the statement is not binlogged if the table is temporary. */ if (!is_temporary_table || !thd->current_stmt_binlog_row_based) - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); - my_ok(thd); // This should return record count + error= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + if (!error) + my_ok(thd); // This should return record count } VOID(pthread_mutex_lock(&LOCK_open)); unlock_table_name(thd, table_list); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 9754d5575e8..1f4ca90157f 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2743,10 +2743,11 @@ bool Delayed_insert::handle_inserts(void) will be binlogged together as one single Table_map event and one single Rows event. */ - thd.binlog_query(THD::ROW_QUERY_TYPE, - row->query.str, row->query.length, - FALSE, FALSE, errcode); - + if (thd.binlog_query(THD::ROW_QUERY_TYPE, + row->query.str, row->query.length, + FALSE, FALSE, errcode)) + goto err; + thd.time_zone_used = backup_time_zone_used; thd.variables.time_zone = backup_time_zone; } @@ -2814,8 +2815,9 @@ bool Delayed_insert::handle_inserts(void) TODO: Move the logging to last in the sequence of rows. */ - if (thd.current_stmt_binlog_row_based) - thd.binlog_flush_pending_rows_event(TRUE); + if (thd.current_stmt_binlog_row_based && + thd.binlog_flush_pending_rows_event(TRUE)) + goto err; if ((error=table->file->extra(HA_EXTRA_NO_CACHE))) { // This shouldn't happen @@ -3267,16 +3269,21 @@ bool select_insert::send_eof() events are in the transaction cache and will be written when ha_autocommit_or_rollback() is issued below. */ - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open() && + (!error || thd->transaction.stmt.modified_non_trans_table)) { int errcode= 0; if (!error) thd->clear_error(); else errcode= query_error_code(thd, killed_status == THD::NOT_KILLED); - thd->binlog_query(THD::ROW_QUERY_TYPE, + if (thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(), thd->query_length(), - trans_table, FALSE, errcode); + trans_table, FALSE, errcode)) + { + table->file->ha_release_auto_increment(); + DBUG_RETURN(1); + } } table->file->ha_release_auto_increment(); @@ -3345,9 +3352,10 @@ void select_insert::abort() { if (mysql_bin_log.is_open()) { int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); - thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(), - thd->query_length(), - transactional_table, FALSE, errcode); + /* error of writing binary log is ignored */ + (void) thd->binlog_query(THD::ROW_QUERY_TYPE, thd->query(), + thd->query_length(), + transactional_table, FALSE, errcode); } if (!thd->current_stmt_binlog_row_based && !can_rollback_data()) thd->transaction.all.modified_non_trans_table= TRUE; @@ -3602,7 +3610,8 @@ select_create::prepare(List &values, SELECT_LEX_UNIT *u) !table->s->tmp_table && !ptr->get_create_info()->table_existed) { - ptr->binlog_show_create_table(tables, count); + if (int error= ptr->binlog_show_create_table(tables, count)) + return error; } return 0; } @@ -3709,7 +3718,7 @@ select_create::prepare(List &values, SELECT_LEX_UNIT *u) DBUG_RETURN(0); } -void +int select_create::binlog_show_create_table(TABLE **tables, uint count) { /* @@ -3748,12 +3757,13 @@ select_create::binlog_show_create_table(TABLE **tables, uint count) if (mysql_bin_log.is_open()) { int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); - thd->binlog_query(THD::STMT_QUERY_TYPE, - query.ptr(), query.length(), - /* is_trans */ TRUE, - /* suppress_use */ FALSE, - errcode); + result= thd->binlog_query(THD::STMT_QUERY_TYPE, + query.ptr(), query.length(), + /* is_trans */ TRUE, + /* suppress_use */ FALSE, + errcode); } + return result; } void select_create::store_values(List &values) @@ -3851,7 +3861,8 @@ void select_create::abort() select_insert::abort(); thd->transaction.stmt.modified_non_trans_table= FALSE; reenable_binlog(thd); - thd->binlog_flush_pending_rows_event(TRUE); + /* possible error of writing binary log is ignored deliberately */ + (void)thd->binlog_flush_pending_rows_event(TRUE); if (m_plock) { diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 326a7517ed6..ee3b442c83a 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -122,7 +122,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, char name[FN_REFLEN]; File file; TABLE *table= NULL; - int error; + int error= 0; String *field_term=ex->field_term,*escaped=ex->escaped; String *enclosed=ex->enclosed; bool is_fifo=0; @@ -504,18 +504,20 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, { int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED); + /* since there is already an error, the possible error of + writing binary log will be ignored */ if (thd->transaction.stmt.modified_non_trans_table) - write_execute_load_query_log_event(thd, ex, - table_list->db, - table_list->table_name, - handle_duplicates, ignore, - transactional_table, - errcode); + (void) write_execute_load_query_log_event(thd, ex, + table_list->db, + table_list->table_name, + handle_duplicates, ignore, + transactional_table, + errcode); else { Delete_file_log_event d(thd, db, transactional_table); d.flags|= LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F; - mysql_bin_log.write(&d); + (void) mysql_bin_log.write(&d); } } } @@ -541,7 +543,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, after this point. */ if (thd->current_stmt_binlog_row_based) - thd->binlog_flush_pending_rows_event(true); + error= thd->binlog_flush_pending_rows_event(true); else { /* @@ -553,13 +555,15 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, if (lf_info.wrote_create_file) { int errcode= query_error_code(thd, killed_status == THD::NOT_KILLED); - write_execute_load_query_log_event(thd, ex, - table_list->db, table_list->table_name, - handle_duplicates, ignore, - transactional_table, - errcode); + error= write_execute_load_query_log_event(thd, ex, + table_list->db, table_list->table_name, + handle_duplicates, ignore, + transactional_table, + errcode); } } + if (error) + goto err; } #endif /*!EMBEDDED_LIBRARY*/ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a2a1494141c..a114d92b124 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2987,7 +2987,7 @@ end_with_restore_list: /* Presumably, REPAIR and binlog writing doesn't require synchronization */ - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + res= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } select_lex->table_list.first= (uchar*) first_table; lex->query_tables=all_tables; @@ -3019,7 +3019,7 @@ end_with_restore_list: /* Presumably, ANALYZE and binlog writing doesn't require synchronization */ - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + res= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } select_lex->table_list.first= (uchar*) first_table; lex->query_tables=all_tables; @@ -3042,7 +3042,7 @@ end_with_restore_list: /* Presumably, OPTIMIZE and binlog writing doesn't require synchronization */ - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + res= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); } select_lex->table_list.first= (uchar*) first_table; lex->query_tables=all_tables; @@ -3159,7 +3159,7 @@ end_with_restore_list: if (incident) { Incident_log_event ev(thd, incident); - mysql_bin_log.write(&ev); + (void) mysql_bin_log.write(&ev); /* error is ignored */ mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE); } DBUG_PRINT("debug", ("Just after generate_incident()")); @@ -3988,7 +3988,8 @@ end_with_restore_list: */ if (!lex->no_write_to_binlog && write_to_binlog) { - write_bin_log(thd, FALSE, thd->query(), thd->query_length()); + if (res= write_bin_log(thd, FALSE, thd->query(), thd->query_length())) + break; } my_ok(thd); } @@ -4566,12 +4567,12 @@ create_sp_error: case SP_KEY_NOT_FOUND: if (lex->drop_if_exists) { - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + res= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), SP_COM_STRING(lex), lex->spname->m_name.str); - res= FALSE; - my_ok(thd); + if (!res) + my_ok(thd); break; } my_error(ER_SP_DOES_NOT_EXIST, MYF(0), diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 329317f4293..275115e3cbd 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -4113,8 +4113,9 @@ static int fast_end_partition(THD *thd, ulonglong copied, } if ((!is_empty) && (!written_bin_log) && - (!thd->lex->no_write_to_binlog)) - write_bin_log(thd, FALSE, thd->query(), thd->query_length()); + (!thd->lex->no_write_to_binlog) && + write_bin_log(thd, FALSE, thd->query(), thd->query_length())) + DBUG_RETURN(TRUE); my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO), (ulong) (copied + deleted), diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index dac96f2e9c4..e85e730db5b 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -34,6 +34,7 @@ static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list); bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) { bool error= 1; + bool binlog_error= 0; TABLE_LIST *ren_table= 0; int to_table; char *rename_log_table[2]= {NULL, NULL}; @@ -174,11 +175,11 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) */ pthread_mutex_unlock(&LOCK_open); - /* Lets hope this doesn't fail as the result will be messy */ if (!silent && !error) { - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); - my_ok(thd); + binlog_error= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + if (!binlog_error) + my_ok(thd); } if (!error) @@ -190,7 +191,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) err: start_waiting_global_read_lock(thd); - DBUG_RETURN(error); + DBUG_RETURN(error || binlog_error); } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index de038f8dc2c..4b10d284611 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1004,8 +1004,8 @@ int reset_slave(THD *thd, Master_info* mi) MY_STAT stat_area; char fname[FN_REFLEN]; int thread_mask= 0, error= 0; - uint sql_errno=0; - const char* errmsg=0; + uint sql_errno=ER_UNKNOWN_ERROR; + const char* errmsg= "Unknown error occured while reseting slave"; DBUG_ENTER("reset_slave"); lock_slave_threads(mi); @@ -1671,7 +1671,8 @@ err: replication events along LOAD DATA processing. @param file pointer to io-cache - @return 0 + @retval 0 success + @retval 1 failure */ int log_loaded_block(IO_CACHE* file) { @@ -1698,7 +1699,8 @@ int log_loaded_block(IO_CACHE* file) Append_block_log_event a(lf_info->thd, lf_info->thd->db, buffer, min(block_len, max_event_size), lf_info->log_delayed); - mysql_bin_log.write(&a); + if (mysql_bin_log.write(&a)) + DBUG_RETURN(1); } else { @@ -1706,7 +1708,8 @@ int log_loaded_block(IO_CACHE* file) buffer, min(block_len, max_event_size), lf_info->log_delayed); - mysql_bin_log.write(&b); + if (mysql_bin_log.write(&b)) + DBUG_RETURN(1); lf_info->wrote_create_file= 1; DBUG_SYNC_POINT("debug_lock.created_file_event",10); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0e36ecfcb46..f5df8481dc4 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1748,9 +1748,10 @@ end: file */ -void write_bin_log(THD *thd, bool clear_error, - char const *query, ulong query_length) +int write_bin_log(THD *thd, bool clear_error, + char const *query, ulong query_length) { + int error= 0; if (mysql_bin_log.is_open()) { int errcode= 0; @@ -1758,9 +1759,10 @@ void write_bin_log(THD *thd, bool clear_error, thd->clear_error(); else errcode= query_error_code(thd, TRUE); - thd->binlog_query(THD::STMT_QUERY_TYPE, - query, query_length, FALSE, FALSE, errcode); + error= thd->binlog_query(THD::STMT_QUERY_TYPE, + query, query_length, FALSE, FALSE, errcode); } + return error; } @@ -2106,7 +2108,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, tables). In this case, we can write the original query into the binary log. */ - write_bin_log(thd, !error, thd->query(), thd->query_length()); + error |= write_bin_log(thd, !error, thd->query(), thd->query_length()); } else if (thd->current_stmt_binlog_row_based && tmp_table_deleted) @@ -2128,7 +2130,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, */ built_query.chop(); // Chop of the last comma built_query.append(" /* generated by server */"); - write_bin_log(thd, !error, built_query.ptr(), built_query.length()); + error|= write_bin_log(thd, !error, built_query.ptr(), built_query.length()); } /* @@ -2147,7 +2149,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, */ built_tmp_query.chop(); // Chop of the last comma built_tmp_query.append(" /* generated by server */"); - write_bin_log(thd, !error, built_tmp_query.ptr(), built_tmp_query.length()); + error|= write_bin_log(thd, !error, built_tmp_query.ptr(), built_tmp_query.length()); } } @@ -3556,9 +3558,9 @@ void sp_prepare_create_field(THD *thd, Create_field *sql_field) RETURN VALUES NONE */ -static inline void write_create_table_bin_log(THD *thd, - const HA_CREATE_INFO *create_info, - bool internal_tmp_table) +static inline int write_create_table_bin_log(THD *thd, + const HA_CREATE_INFO *create_info, + bool internal_tmp_table) { /* Don't write statement if: @@ -3571,7 +3573,8 @@ static inline void write_create_table_bin_log(THD *thd, (!thd->current_stmt_binlog_row_based || (thd->current_stmt_binlog_row_based && !(create_info->options & HA_LEX_CREATE_TMP_TABLE)))) - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + return write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + return 0; } @@ -3837,8 +3840,7 @@ bool mysql_create_table_no_lock(THD *thd, push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), alias); - error= 0; - write_create_table_bin_log(thd, create_info, internal_tmp_table); + error= write_create_table_bin_log(thd, create_info, internal_tmp_table); goto err; } my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias); @@ -3959,8 +3961,7 @@ bool mysql_create_table_no_lock(THD *thd, thd->thread_specific_used= TRUE; } - write_create_table_bin_log(thd, create_info, internal_tmp_table); - error= FALSE; + error= write_create_table_bin_log(thd, create_info, internal_tmp_table); unlock_and_end: VOID(pthread_mutex_unlock(&LOCK_open)); @@ -3975,7 +3976,7 @@ warn: ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), alias); create_info->table_existed= 1; // Mark that table existed - write_create_table_bin_log(thd, create_info, internal_tmp_table); + error= write_create_table_bin_log(thd, create_info, internal_tmp_table); goto unlock_and_end; } @@ -5448,18 +5449,20 @@ binlog: create_info, FALSE /* show_database */); DBUG_ASSERT(result == 0); // store_create_info() always return 0 - write_bin_log(thd, TRUE, query.ptr(), query.length()); + if (write_bin_log(thd, TRUE, query.ptr(), query.length())) + goto err; } } else // Case 1 - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + if (write_bin_log(thd, TRUE, thd->query(), thd->query_length())) + goto err; } /* Case 3 and 4 does nothing under RBR */ } - else - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + else if (write_bin_log(thd, TRUE, thd->query(), thd->query_length())) + goto err; res= FALSE; @@ -5547,7 +5550,7 @@ mysql_discard_or_import_tablespace(THD *thd, error=1; if (error) goto err; - write_bin_log(thd, FALSE, thd->query(), thd->query_length()); + error= write_bin_log(thd, FALSE, thd->query(), thd->query_length()); err: ha_autocommit_or_rollback(thd, error); @@ -6558,11 +6561,13 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, thd->clear_error(); Query_log_event qinfo(thd, thd->query(), thd->query_length(), 0, FALSE, 0); - mysql_bin_log.write(&qinfo); + if (error= mysql_bin_log.write(&qinfo)) + goto view_err_unlock; } my_ok(thd); } +view_err_unlock: unlock_table_names(thd, table_list, (TABLE_LIST*) 0); view_err: @@ -6810,8 +6815,9 @@ view_err: if (!error) { - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); - my_ok(thd); + error= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + if (!error) + my_ok(thd); } else if (error > 0) { @@ -7299,8 +7305,9 @@ view_err: if (rename_temporary_table(thd, new_table, new_db, new_name)) goto err1; /* We don't replicate alter table statement on temporary tables */ - if (!thd->current_stmt_binlog_row_based) - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + if (!thd->current_stmt_binlog_row_based && + write_bin_log(thd, TRUE, thd->query(), thd->query_length())) + DBUG_RETURN(TRUE); goto end_temporary; } @@ -7463,7 +7470,8 @@ view_err: DBUG_ASSERT(!(mysql_bin_log.is_open() && thd->current_stmt_binlog_row_based && (create_info->options & HA_LEX_CREATE_TMP_TABLE))); - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + if (write_bin_log(thd, TRUE, thd->query(), thd->query_length())) + DBUG_RETURN(TRUE); if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME)) { diff --git a/sql/sql_tablespace.cc b/sql/sql_tablespace.cc index fcc442a8f9a..65107f8679e 100644 --- a/sql/sql_tablespace.cc +++ b/sql/sql_tablespace.cc @@ -66,6 +66,6 @@ int mysql_alter_tablespace(THD *thd, st_alter_tablespace *ts_info) ha_resolve_storage_engine_name(hton), "TABLESPACE or LOGFILE GROUP"); } - write_bin_log(thd, FALSE, thd->query(), thd->query_length()); - DBUG_RETURN(FALSE); + error= write_bin_log(thd, FALSE, thd->query(), thd->query_length()); + DBUG_RETURN(error); } diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index a251a533622..ba0515d38ad 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -507,7 +507,7 @@ end: if (!result) { - write_bin_log(thd, TRUE, stmt_query.ptr(), stmt_query.length()); + result= write_bin_log(thd, TRUE, stmt_query.ptr(), stmt_query.length()); } VOID(pthread_mutex_unlock(&LOCK_open)); diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index c6b41b59a3f..3ade9fbc0b1 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -506,8 +506,8 @@ int mysql_create_function(THD *thd,udf_func *udf) rw_unlock(&THR_LOCK_udf); /* Binlog the create function. */ - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); - + if (write_bin_log(thd, TRUE, thd->query(), thd->query_length())) + DBUG_RETURN(1); DBUG_RETURN(0); err: @@ -581,8 +581,8 @@ int mysql_drop_function(THD *thd,const LEX_STRING *udf_name) rw_unlock(&THR_LOCK_udf); /* Binlog the drop function. */ - write_bin_log(thd, TRUE, thd->query(), thd->query_length()); - + if (write_bin_log(thd, TRUE, thd->query(), thd->query_length())) + DBUG_RETURN(1); DBUG_RETURN(0); err: rw_unlock(&THR_LOCK_udf); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 26f40c7fa9f..433e2619aca 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1868,9 +1868,10 @@ void multi_update::abort() into repl event. */ int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED); - thd->binlog_query(THD::ROW_QUERY_TYPE, - thd->query(), thd->query_length(), - transactional_tables, FALSE, errcode); + /* the error of binary logging is ignored */ + (void)thd->binlog_query(THD::ROW_QUERY_TYPE, + thd->query(), thd->query_length(), + transactional_tables, FALSE, errcode); } thd->transaction.all.modified_non_trans_table= TRUE; } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 83cebf1e3da..c6d412112c2 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -662,8 +662,9 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, buff.append(views->source.str, views->source.length); int errcode= query_error_code(thd, TRUE); - thd->binlog_query(THD::STMT_QUERY_TYPE, - buff.ptr(), buff.length(), FALSE, FALSE, errcode); + if (thd->binlog_query(THD::STMT_QUERY_TYPE, + buff.ptr(), buff.length(), FALSE, FALSE, errcode)) + res= TRUE; } VOID(pthread_mutex_unlock(&LOCK_open)); @@ -1652,7 +1653,8 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) /* if something goes wrong, bin-log with possible error code, otherwise bin-log with error code cleared. */ - write_bin_log(thd, !something_wrong, thd->query(), thd->query_length()); + if (write_bin_log(thd, !something_wrong, thd->query(), thd->query_length())) + something_wrong= 1; } VOID(pthread_mutex_unlock(&LOCK_open)); From cfa7e83d6deee0acb2c003e94617be115e07814e Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Mon, 25 Jan 2010 17:46:48 +0200 Subject: [PATCH 135/157] Bug #47142 "slave start until" stops 1 event too late in 4.1 to 5.0 replication When replicating from 4.1 master to 5.0 slave START SLAVE UNTIL can stop too late. The necessary in calculating of the beginning of an event the event's length did not correspond to the master's genuine information at the event's execution time. That piece of info was changed at the event's relay-logging due to binlog_version<4 event conversion by IO thread. Fixed with storing the master genuine Query_log_event size into a new status variable at relay-logging of the event. The stored info is extacted at the event execution and participate further to caclulate the correct start position of the event in the until-pos stopping routine. The new status variable's algorithm will be only active when the event comes from the master of version < 5.0 (binlog_version < 4). mysql-test/r/rpl_until.result: results changed. mysql-test/std_data/bug47142_master-bin.000001: a binlog from 4.1 master to replace one of the running 5.x master is added as part of Bug #47142 regression test. mysql-test/t/rpl_until.test: Regression test for Bug #47142 is added. sql/log_event.cc: Storing and extracting the master's genuine size of the event from the status var of the event packet header. The binlog_version<4 query-log-event is a. converted into the modern binlog_version==4 to store the original size of the event into a new status var; the converted representation goes into the relay log. b. the converted event is read out and the stored size is engaged in the start pos calculation. The new status is active only for events that IO thread instantiates for the sake of the conversion. sql/log_event.h: Incrementing the max szie of MAX_SIZE_LOG_EVENT_STATUS because of the new status var; Defining the new status variable to hold the master's genuine event size; Augmenting the Query_log_event with a new member to hold a value to store/extact from the status var of the event packet header. --- mysql-test/r/rpl_until.result | 18 +++++++++ .../std_data/bug47142_master-bin.000001 | Bin 0 -> 386 bytes mysql-test/t/rpl_until.test | 36 +++++++++++++++++ sql/log_event.cc | 37 ++++++++++++++++-- sql/log_event.h | 15 ++++++- 5 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 mysql-test/std_data/bug47142_master-bin.000001 diff --git a/mysql-test/r/rpl_until.result b/mysql-test/r/rpl_until.result index 60b956785ba..476e56878db 100644 --- a/mysql-test/r/rpl_until.result +++ b/mysql-test/r/rpl_until.result @@ -194,3 +194,21 @@ start slave sql_thread; start slave until master_log_file='master-bin.000001', master_log_pos=776; Warnings: Note 1254 Slave is already running +stop slave; +drop table if exists t1; +Warnings: +Note 1051 Unknown table 't1' +flush logs; +show binary logs; +Log_name File_size +master-bin.000001 # +master-bin.000002 # +reset slave; +start slave until master_log_file='master-bin.000001', master_log_pos=294 /* to stop right before DROP */; +show tables /* t1 must exist */; +Tables_in_test +t1 +drop table t1; +stop slave; +reset slave; +reset master; diff --git a/mysql-test/std_data/bug47142_master-bin.000001 b/mysql-test/std_data/bug47142_master-bin.000001 new file mode 100644 index 0000000000000000000000000000000000000000..d1a089a784a6596f5c92b2ffdd06da90951ad9fc GIT binary patch literal 386 zcmaJ-K}rKb5S(c69et97>@JxQye&Rp4;}=GczlSaDGcYom1G&aJDy?%}ZJu6l57w7# z_LwZsQvbEKE|8C+?Zo*3+kpbibOw6WlePp=FGl#6R3ssU3z$KIgL+OR3clU;9sy literal 0 HcmV?d00001 diff --git a/mysql-test/t/rpl_until.test b/mysql-test/t/rpl_until.test index c404ea7e58b..b533c2192b0 100644 --- a/mysql-test/t/rpl_until.test +++ b/mysql-test/t/rpl_until.test @@ -84,4 +84,40 @@ start slave until relay_log_file='slave-relay-bin.000002', master_log_pos=561; start slave sql_thread; start slave until master_log_file='master-bin.000001', master_log_pos=776; +# +# Bug #47142 "slave start until" stops 1 event too late in 4.1 to 5.0 replication +# +# testing fixes that refine the start position of prior-5.0 master's event +# and by that provide correct execution of +# START SLAVE UNTIL ... master_log_pos= x; +# Keep the test at the end of the file because it manipulates with binlog files +# to substitute the genuine one with a prepared on 4.1 server. +# + +connection slave; +stop slave; + +connection master; +drop table if exists t1; +flush logs; +--source include/show_binary_logs.inc +--remove_file $MYSQLTEST_VARDIR/log/master-bin.000001 +--copy_file $MYSQL_TEST_DIR/std_data/bug47142_master-bin.000001 $MYSQLTEST_VARDIR/log/master-bin.000001 + +connection slave; +reset slave; +start slave until master_log_file='master-bin.000001', master_log_pos=294 /* to stop right before DROP */; +--source include/wait_for_slave_sql_to_stop.inc + +show tables /* t1 must exist */; + +# clean-up of Bug #47142 testing + +drop table t1; # drop on slave only, master does not have t1. +stop slave; +reset slave; + +connection master; +reset master; + # End of 4.1 tests diff --git a/sql/log_event.cc b/sql/log_event.cc index 40e29e58ab6..f32fcb0056c 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1271,10 +1271,22 @@ bool Query_log_event::write(IO_CACHE* file) int8store(start, table_map_for_update); start+= 8; } + if (master_data_written != 0) + { + /* + Q_MASTER_DATA_WRITTEN_CODE only exists in relay logs where the master + has binlog_version<4 and the slave has binlog_version=4. See comment + for master_data_written in log_event.h for details. + */ + *start++= Q_MASTER_DATA_WRITTEN_CODE; + int4store(start, master_data_written); + start+= 4; + } + /* NOTE: When adding new status vars, please don't forget to update - the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update function - code_name in this file. + the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update the function + code_name() in this file. Here there could be code like if (command-line-option-which-says-"log_this_variable" && inited) @@ -1354,6 +1366,7 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, auto_increment_offset(thd_arg->variables.auto_increment_offset), lc_time_names_number(thd_arg->variables.lc_time_names->number), charset_database_number(0), + master_data_written(0), table_map_for_update((ulonglong)thd_arg->table_map_for_update) { time_t end_time; @@ -1481,6 +1494,7 @@ code_name(int code) case Q_LC_TIME_NAMES_CODE: return "Q_LC_TIME_NAMES_CODE"; case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE"; case Q_TABLE_MAP_FOR_UPDATE_CODE: return "Q_TABLE_MAP_FOR_UPDATE_CODE"; + case Q_MASTER_DATA_WRITTEN_CODE: return "Q_MASTER_DATA_WRITTEN_CODE"; } sprintf(buf, "CODE#%d", code); return buf; @@ -1518,7 +1532,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, flags2_inited(0), sql_mode_inited(0), charset_inited(0), auto_increment_increment(1), auto_increment_offset(1), time_zone_len(0), lc_time_names_number(0), charset_database_number(0), - table_map_for_update(0) + table_map_for_update(0), master_data_written(0) { ulong data_len; uint32 tmp; @@ -1574,6 +1588,18 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, DBUG_PRINT("info", ("Query_log_event has status_vars_len: %u", (uint) status_vars_len)); tmp-= 2; + } + else + { + /* + server version < 5.0 / binlog_version < 4 master's event is + relay-logged with storing the original size of the event in + Q_MASTER_DATA_WRITTEN_CODE status variable. + The size is to be restored at reading Q_MASTER_DATA_WRITTEN_CODE-marked + event from the relay log. + */ + DBUG_ASSERT(description_event->binlog_version < 4); + master_data_written= data_written; } /* We have parsed everything we know in the post header for QUERY_EVENT, @@ -1665,6 +1691,11 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, table_map_for_update= uint8korr(pos); pos+= 8; break; + case Q_MASTER_DATA_WRITTEN_CODE: + CHECK_SPACE(pos, end, 4); + data_written= master_data_written= uint4korr(pos); + pos+= 4; + break; default: /* That's why you must write status vars in growing order of code */ DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\ diff --git a/sql/log_event.h b/sql/log_event.h index 45e3d11b48c..10b374199de 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -212,7 +212,8 @@ struct sql_ex_info 1 + 1 + 255 /* type, length, time_zone */ + \ 1 + 2 /* type, lc_time_names_number */ + \ 1 + 2 /* type, charset_database_number */ + \ - 1 + 8 /* type, table_map_for_update */) + 1 + 8 /* type, table_map_for_update */ + \ + 1 + 4 /* type, master_data_written */) #define MAX_LOG_EVENT_HEADER ( /* in order of Query_log_event::write */ \ LOG_EVENT_HEADER_LEN + /* write_header */ \ QUERY_HEADER_LEN + /* write_data */ \ @@ -278,6 +279,9 @@ struct sql_ex_info #define Q_CHARSET_DATABASE_CODE 8 #define Q_TABLE_MAP_FOR_UPDATE_CODE 9 + +#define Q_MASTER_DATA_WRITTEN_CODE 10 + /* Intvar event post-header */ #define I_TYPE_OFFSET 0 @@ -810,6 +814,15 @@ public: statement, for other query statements, this will be zero. */ ulonglong table_map_for_update; + /* + Holds the original length of a Query_log_event that comes from a + master of version < 5.0 (i.e., binlog_version < 4). When the IO + thread writes the relay log, it augments the Query_log_event with a + Q_MASTER_DATA_WRITTEN_CODE status_var that holds the original event + length. This field is initialized to non-zero in the SQL thread when + it reads this augmented event. + */ + uint32 master_data_written; #ifndef MYSQL_CLIENT From c7cb4b3c42ceeabf0e6ce289dccee560896faacc Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 26 Jan 2010 10:47:43 +0200 Subject: [PATCH 136/157] fix a windows test run bug with debug binaries : dbug frame should be exited before destroying the thread local storage. --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index db0453dc364..1fcd046f870 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1949,10 +1949,10 @@ bool one_thread_per_connection_end(THD *thd, bool put_in_cache) /* It's safe to broadcast outside a lock (COND... is not deleted here) */ DBUG_PRINT("signal", ("Broadcasting COND_thread_count")); + DBUG_LEAVE; // Must match DBUG_ENTER() my_thread_end(); (void) pthread_cond_broadcast(&COND_thread_count); - DBUG_LEAVE; // Must match DBUG_ENTER() pthread_exit(0); return 0; // Avoid compiler warnings } From 7920e89a47a6cc8f65783528291ce87ba5b19074 Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Tue, 26 Jan 2010 15:05:19 -0200 Subject: [PATCH 137/157] Bug#49491: Much overhead for MD5() and SHA1() on short strings MySQL's hash functions MD5 and SHA relied on the somewhat slow sprintf function to convert the digests to hex representations. This patch replaces the sprintf with a specific and inline hex conversion function. Patch contributed by Jan Steemann. sql/item_strfunc.cc: Add a hex conversion function. --- sql/item_strfunc.cc | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index ecd839d8378..4cdeeef6c78 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -42,6 +42,20 @@ C_MODE_END String my_empty_string("",default_charset_info); +/* + Convert an array of bytes to a hexadecimal representation. + + Used to generate a hexadecimal representation of a message digest. +*/ +static void array_to_hex(char *to, const char *str, uint len) +{ + const char *str_end= str + len; + for (; str != str_end; ++str) + { + *to++= _dig_vec_lower[((uchar) *str) >> 4]; + *to++= _dig_vec_lower[((uchar) *str) & 0x0F]; + } +} bool Item_str_func::fix_fields(THD *thd, Item **ref) @@ -114,12 +128,7 @@ String *Item_func_md5::val_str(String *str) null_value=1; return 0; } - sprintf((char *) str->ptr(), - "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - digest[0], digest[1], digest[2], digest[3], - digest[4], digest[5], digest[6], digest[7], - digest[8], digest[9], digest[10], digest[11], - digest[12], digest[13], digest[14], digest[15]); + array_to_hex((char *) str->ptr(), (const char*) digest, 16); str->length((uint) 32); return str; } @@ -160,15 +169,7 @@ String *Item_func_sha::val_str(String *str) if (!( str->alloc(SHA1_HASH_SIZE*2) || (mysql_sha1_result(&context,digest)))) { - sprintf((char *) str->ptr(), - "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\ -%02x%02x%02x%02x%02x%02x%02x%02x", - digest[0], digest[1], digest[2], digest[3], - digest[4], digest[5], digest[6], digest[7], - digest[8], digest[9], digest[10], digest[11], - digest[12], digest[13], digest[14], digest[15], - digest[16], digest[17], digest[18], digest[19]); - + array_to_hex((char *) str->ptr(), (const char*) digest, SHA1_HASH_SIZE); str->length((uint) SHA1_HASH_SIZE*2); null_value=0; return str; From c12c9780cdbe965bcdce0326b14a171d2f2b8635 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 27 Jan 2010 10:52:13 +0800 Subject: [PATCH 138/157] Bug #49191 rpl_get_master_version_and_clock failed on PB2: COM_REGISTER_SLAVE failed The 'rpl_get_master_version_and_clock' test verifies if the slave I/O thread tries to reconnect to master when it tries to get the values of the UNIX_TIMESTAMP, SERVER_ID from master under network disconnection. So the master server is restarted for making the transient network disconnection, during the period the COM_REGISTER_SLAVE failures are produced in server log file when the slave I/O thread tries to register on master. To fix the problem, suppress COM_REGISTER_SLAVE failures in server log file by mtr suppression, because they are expected. mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result: Removed mtr.add_suppression("Get master clock failed with error: ") and mtr.add_suppression("Get master SERVER_ID failed with error: "). Because they are suppressed globally. --- mysql-test/collections/default.experimental | 1 - .../rpl/r/rpl_get_master_version_and_clock.result | 5 ++--- .../suite/rpl/t/rpl_get_master_version_and_clock.test | 11 ++++++----- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 2e31063a6db..9c4055cd19e 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -17,7 +17,6 @@ main.plugin_load @solaris # Bug#42144 ndb.* # joro : NDB tests marked as experimental as agreed with bochklin -rpl.rpl_get_master_version_and_clock* # Bug #49191 2009-12-01 Daogang rpl_get_master_version_and_clock failed on PB2: COM_REGISTER_SLAVE failed rpl.rpl_innodb_bug28430* @solaris # Bug#46029 rpl_ndb.* # joro : NDB tests marked as experimental as agreed with bochklin diff --git a/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result b/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result index 5f2a55b5e35..d054cb573d3 100644 --- a/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result +++ b/mysql-test/suite/rpl/r/rpl_get_master_version_and_clock.result @@ -4,10 +4,9 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; -call mtr.add_suppression("Get master clock failed with error: "); -call mtr.add_suppression("Get master SERVER_ID failed with error: "); -call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again"); +call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: .*"); call mtr.add_suppression("Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; .*"); +call mtr.add_suppression("Slave I/O thread .* register on master"); SELECT IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP"); IS_FREE_LOCK("debug_lock.before_get_UNIX_TIMESTAMP") 1 diff --git a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test index 69c63eaa69f..24309e8a14a 100644 --- a/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test +++ b/mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test @@ -16,12 +16,13 @@ source include/master-slave.inc; source include/have_debug.inc; -call mtr.add_suppression("Get master clock failed with error: "); -call mtr.add_suppression("Get master SERVER_ID failed with error: "); -call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: failed registering on master, reconnecting to try again"); -call mtr.add_suppression("Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; .*"); -#Test case 1: Try to get the value of the UNIX_TIMESTAMP from master under network disconnection + connection slave; +call mtr.add_suppression("Slave I/O: Master command COM_REGISTER_SLAVE failed: .*"); +call mtr.add_suppression("Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; .*"); +call mtr.add_suppression("Slave I/O thread .* register on master"); + +#Test case 1: Try to get the value of the UNIX_TIMESTAMP from master under network disconnection let $debug_saved= `select @@global.debug`; let $debug_lock= "debug_lock.before_get_UNIX_TIMESTAMP"; From 694d50c71efc079c794fc81fb13d49ce5036ce36 Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Wed, 27 Jan 2010 11:38:50 +0100 Subject: [PATCH 139/157] Bug#50409 Solaris 8 compatibility broken by assumption about printstack() being present When Bug#47391 was fixed, no assumption was made that support for Solaris 8 was needed. Solaris 8 lacks printstack(), and the build breaks because of this. This patch adds a test for the presence of printstack() to configure.in for 5.0, and uses HAVE_PRINTSTACK to make decisions rather than the __sun define. --- configure.in | 2 +- sql/stacktrace.c | 2 +- sql/stacktrace.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.in b/configure.in index 405ebddadbe..a399ccb2909 100644 --- a/configure.in +++ b/configure.in @@ -2128,7 +2128,7 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bzero chsize cuserid fchmod fcntl \ shmget shmat shmdt shmctl sigaction sigemptyset sigaddset \ sighold sigset sigthreadmask \ snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr strtol \ - strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr) + strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr printstack) # # diff --git a/sql/stacktrace.c b/sql/stacktrace.c index 295a7a3e1e2..a8648ca4e5a 100644 --- a/sql/stacktrace.c +++ b/sql/stacktrace.c @@ -227,7 +227,7 @@ stack trace is much more helpful in diagnosing the problem, so please do \n\ resolve it\n"); } -#elif defined(__sun) +#elif defined(HAVE_PRINTSTACK) /* Use Solaris' symbolic stack trace routine. */ #include diff --git a/sql/stacktrace.h b/sql/stacktrace.h index 718b545b775..1366a6cf996 100644 --- a/sql/stacktrace.h +++ b/sql/stacktrace.h @@ -35,7 +35,7 @@ void check_thread_lib(void); #define HAVE_STACKTRACE extern void set_exception_pointers(EXCEPTION_POINTERS *ep); #define init_stacktrace() {} -#elif defined(__sun) +#elif defined(HAVE_PRINTSTACK) #define HAVE_STACKTRACE #define init_stacktrace() {} #endif From 35c6bb89e64fd87a0ce1b51eab8b757dbdfc228d Mon Sep 17 00:00:00 2001 From: Magne Mahre Date: Wed, 27 Jan 2010 13:23:28 +0100 Subject: [PATCH 140/157] WL#5182 Remove more deprecated 4.1/5.0 features WL#5182 is a follow-up to WL#5154, deprecating a few more options and system variables. client/client_priv.h: The warning message has been changed to not include a specific version number in the text. client/mysql.cc: --no-tee is deprecated client/mysqldump.c: --all is deprecated -a now points to create-options mysql-test/r/mysqlbinlog.result: Warning text changed mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result: Warning text changed sql/mysql_priv.h: The warning message has been changed to not include a specific version number in the text. sql/mysqld.cc: --use-symbolic-links is deprecated -s now points to --symbolic-links --warnings is deprecated -W now points to --log-warnings myisam_max_extra_sort_file_size is deprecated record_buffer is deprecated --log-update is deprecated --sql-bin-update-same is deprecated --skip-locking is deprecated --skip-symlink is deprecated --enable-locking is deprecated --delay-key-write-for-all-tables is deprecated --- client/client_priv.h | 5 ++- client/mysql.cc | 2 +- client/mysqldump.c | 7 +++- mysql-test/r/mysqlbinlog.result | 6 +-- .../suite/rpl/r/rpl_row_mysqlbinlog.result | 4 +- sql/mysql_priv.h | 2 +- sql/mysqld.cc | 40 ++++++++++++++++--- 7 files changed, 50 insertions(+), 16 deletions(-) diff --git a/client/client_priv.h b/client/client_priv.h index 9d2fc2be141..689f7277c2e 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -37,7 +37,7 @@ #define WARN_DEPRECATED(Ver,Old,New) \ do { \ printf("Warning: The option '%s' is deprecated and will be removed " \ - "in MySQL %s. Please use %s instead.\n", (Old), (Ver), (New)); \ + "in a future release. Please use %s instead.\n", (Old), (New)); \ } while(0); enum options_client @@ -57,7 +57,7 @@ enum options_client OPT_PROMPT, OPT_IGN_LINES,OPT_TRANSACTION,OPT_MYSQL_PROTOCOL, OPT_SHARED_MEMORY_BASE_NAME, OPT_FRM, OPT_SKIP_OPTIMIZATION, OPT_COMPATIBLE, OPT_RECONNECT, OPT_DELIMITER, OPT_SECURE_AUTH, - OPT_OPEN_FILES_LIMIT, OPT_SET_CHARSET, OPT_CREATE_OPTIONS, OPT_SERVER_ARG, + OPT_OPEN_FILES_LIMIT, OPT_SET_CHARSET, OPT_SERVER_ARG, OPT_POSITION, OPT_STOP_POSITION, OPT_START_DATETIME, OPT_STOP_DATETIME, OPT_SIGINT_IGNORE, OPT_HEXBLOB, OPT_ORDER_BY_PRIMARY, OPT_COUNT, #ifdef HAVE_NDBCLUSTER_DB @@ -90,5 +90,6 @@ enum options_client OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE, OPT_WRITE_BINLOG, OPT_DUMP_DATE, OPT_FIRST_SLAVE, + OPT_ALL, OPT_MAX_CLIENT_OPTION }; diff --git a/client/mysql.cc b/client/mysql.cc index b3b73fdb468..82a29816b8e 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1630,7 +1630,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), init_tee(argument); break; case OPT_NOTEE: - printf("WARNING: option deprecated; use --disable-tee instead.\n"); + WARN_DEPRECATED(VER_CELOSIA, "--no-tee", "--disable-tee"); if (opt_outfile) end_tee(); break; diff --git a/client/mysqldump.c b/client/mysqldump.c index 25a8d7b0f6f..8a50c57201c 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -179,7 +179,7 @@ HASH ignore_table; static struct my_option my_long_options[] = { - {"all", 'a', "Deprecated. Use --create-options instead.", + {"all", OPT_ALL, "Deprecated. Use --create-options instead.", (uchar**) &create_options, (uchar**) &create_options, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"all-databases", 'A', @@ -230,7 +230,7 @@ static struct my_option my_long_options[] = {"compress", 'C', "Use compression in server/client protocol.", (uchar**) &opt_compress, (uchar**) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"create-options", OPT_CREATE_OPTIONS, + {"create-options", 'a', "Include all MySQL specific create options.", (uchar**) &create_options, (uchar**) &create_options, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -762,6 +762,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'O': WARN_DEPRECATED(VER_CELOSIA, "--set-variable", "--variable-name=value"); break; + case (int) OPT_ALL: + WARN_DEPRECATED(VER_CELOSIA, "--all", "--create-options"); + break; case (int) OPT_FIRST_SLAVE: WARN_DEPRECATED(VER_CELOSIA, "--first-slave", "--lock-all-tables"); break; diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index f5c40202101..b7aa981f834 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -93,7 +93,7 @@ ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- --position -- -Warning: The option '--position' is deprecated and will be removed in MySQL 5.6. Please use --start-position instead. +Warning: The option '--position' is deprecated and will be removed in a future release. Please use --start-position instead. /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -194,7 +194,7 @@ ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- --position -- -Warning: The option '--position' is deprecated and will be removed in MySQL 5.6. Please use --start-position instead. +Warning: The option '--position' is deprecated and will be removed in a future release. Please use --start-position instead. /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -235,7 +235,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; -Warning: The option '--position' is deprecated and will be removed in MySQL 5.6. Please use --start-position instead. +Warning: The option '--position' is deprecated and will be removed in a future release. Please use --start-position instead. /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; diff --git a/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result b/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result index 449407742de..538764da738 100644 --- a/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result +++ b/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result @@ -152,7 +152,7 @@ c1 c3 c4 c5 5 2006-02-22 00:00:00 Tested in Texas 11 --- Test 2 position test -- -Warning: The option '--position' is deprecated and will be removed in MySQL 5.6. Please use --start-position instead. +Warning: The option '--position' is deprecated and will be removed in a future release. Please use --start-position instead. /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -315,7 +315,7 @@ ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; --- Test 7 reading stdin w/position -- -Warning: The option '--position' is deprecated and will be removed in MySQL 5.6. Please use --start-position instead. +Warning: The option '--position' is deprecated and will be removed in a future release. Please use --start-position instead. /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index e99effe1dcb..34f29e7c458 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -124,7 +124,7 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); (Old), (Ver), (New)); \ else \ sql_print_warning("The syntax '%s' is deprecated and will be removed " \ - "in MySQL %s. Please use %s instead.", (Old), (Ver), (New)); \ + "in a future release. Please use %s instead.", (Old), (New)); \ } while(0) extern MYSQL_PLUGIN_IMPORT CHARSET_INFO *system_charset_info; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1fcd046f870..40026867aaf 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5711,6 +5711,9 @@ enum options_mysqld OPT_TABLE_LOCK_WAIT_TIMEOUT, OPT_PLUGIN_LOAD, OPT_PLUGIN_DIR, + OPT_SYMBOLIC_LINKS, + OPT_WARNINGS, + OPT_RECORD_BUFFER_OLD, OPT_LOG_OUTPUT, OPT_PORT_OPEN_TIMEOUT, OPT_PROFILING, @@ -6532,7 +6535,7 @@ log and this option does nothing anymore.", {"transaction-isolation", OPT_TX_ISOLATION, "Default transaction isolation level.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"use-symbolic-links", 's', "Enable symbolic link support. Deprecated option; use --symbolic-links instead.", + {"use-symbolic-links", OPT_SYMBOLIC_LINKS, "Enable symbolic link support. Deprecated option; use --symbolic-links instead.", (uchar**) &my_use_symdir, (uchar**) &my_use_symdir, 0, GET_BOOL, NO_ARG, IF_PURIFY(0,1), 0, 0, 0, 0, 0}, {"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG, @@ -6542,7 +6545,7 @@ log and this option does nothing anymore.", 0, 0}, {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"warnings", 'W', "Deprecated; use --log-warnings instead.", + {"warnings", OPT_WARNINGS, "Deprecated; use --log-warnings instead.", (uchar**) &global_system_variables.log_warnings, (uchar**) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, ULONG_MAX, 0, 0, 0}, @@ -6795,7 +6798,8 @@ The minimum value for this variable is 4096.", (uchar**) &myisam_data_pointer_size, 0, GET_ULONG, REQUIRED_ARG, 6, 2, 7, 0, 1, 0}, {"myisam_max_extra_sort_file_size", OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE, - "Deprecated option", + "This is a deprecated option that does nothing anymore. It will be removed in MySQL " + VER_CELOSIA, (uchar**) &global_system_variables.myisam_max_extra_sort_file_size, (uchar**) &max_system_variables.myisam_max_extra_sort_file_size, 0, GET_ULL, REQUIRED_ARG, (ulonglong) MI_MAX_TEMP_LENGTH, @@ -6952,8 +6956,8 @@ The minimum value for this variable is 4096.", (uchar**) &max_system_variables.read_rnd_buff_size, 0, GET_ULONG, REQUIRED_ARG, 256*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0}, - {"record_buffer", OPT_RECORD_BUFFER, - "Alias for read_buffer_size", + {"record_buffer", OPT_RECORD_BUFFER_OLD, + "Alias for read_buffer_size. This variable is deprecated and will be removed in a future release.", (uchar**) &global_system_variables.read_buff_size, (uchar**) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0}, @@ -7966,6 +7970,9 @@ mysqld_get_one_option(int optid, print_version(); exit(0); #endif /*EMBEDDED_LIBRARY*/ + case OPT_WARNINGS: + WARN_DEPRECATED(NULL, VER_CELOSIA, "--warnings", "--log-warnings"); + /* Note: fall-through to 'W' */ case 'W': if (!argument) global_system_variables.log_warnings++; @@ -7987,6 +7994,9 @@ mysqld_get_one_option(int optid, case (int) OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD: WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-bin-trust-routine-creators", "--log-bin-trust-function-creators"); break; + case (int) OPT_ENABLE_LOCK: + WARN_DEPRECATED(NULL, VER_CELOSIA, "--enable-locking", "--external-locking"); + break; case (int) OPT_BIG_TABLES: thd_startup_options|=OPTION_BIG_TABLES; break; @@ -7997,6 +8007,7 @@ mysqld_get_one_option(int optid, opt_myisam_log=1; break; case (int) OPT_UPDATE_LOG: + WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-update", "--log-bin"); opt_update_log=1; break; case (int) OPT_BIN_LOG: @@ -8164,8 +8175,18 @@ mysqld_get_one_option(int optid, "give threads different priorities."); break; case (int) OPT_SKIP_LOCK: + WARN_DEPRECATED(NULL, VER_CELOSIA, "--skip-locking", "--skip-external-locking"); opt_external_locking=0; break; + case (int) OPT_SQL_BIN_UPDATE_SAME: + WARN_DEPRECATED(NULL, VER_CELOSIA, "--sql-bin-update-same", "the binary log"); + break; + case (int) OPT_RECORD_BUFFER_OLD: + WARN_DEPRECATED(NULL, VER_CELOSIA, "record_buffer", "read_buffer_size"); + break; + case (int) OPT_SYMBOLIC_LINKS: + WARN_DEPRECATED(NULL, VER_CELOSIA, "--use-symbolic-links", "--symbolic-links"); + break; case (int) OPT_SKIP_HOST_CACHE: opt_specialflag|= SPECIAL_NO_HOST_CACHE; break; @@ -8191,6 +8212,7 @@ mysqld_get_one_option(int optid, test_flags|=TEST_NO_STACKTRACE; break; case (int) OPT_SKIP_SYMLINKS: + WARN_DEPRECATED(NULL, VER_CELOSIA, "--skip-symlink", "--skip-symbolic-links"); my_use_symdir=0; break; case (int) OPT_BIND_ADDRESS: @@ -8266,6 +8288,9 @@ mysqld_get_one_option(int optid, server_id_supplied = 1; break; case OPT_DELAY_KEY_WRITE_ALL: + WARN_DEPRECATED(NULL, VER_CELOSIA, + "--delay-key-write-for-all-tables", + "--delay-key-write=ALL"); if (argument != disabled_my_option) argument= (char*) "ALL"; /* Fall through */ @@ -8281,6 +8306,11 @@ mysqld_get_one_option(int optid, delay_key_write_options= (uint) type-1; } break; + case OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE: + sql_print_warning("--myisam_max_extra_sort_file_size is deprecated and " + "does nothing in this version. It will be removed in " + "a future release."); + break; case OPT_CHARSETS_DIR: strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir)-1); charsets_dir = mysql_charsets_dir; From 29cd733fce232d84758b262121a5dd9b9c0031a6 Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Wed, 27 Jan 2010 15:20:03 +0200 Subject: [PATCH 141/157] bug#47142 improving comments --- sql/log_event.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/log_event.h b/sql/log_event.h index 10b374199de..3b62c6aab76 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -820,7 +820,8 @@ public: thread writes the relay log, it augments the Query_log_event with a Q_MASTER_DATA_WRITTEN_CODE status_var that holds the original event length. This field is initialized to non-zero in the SQL thread when - it reads this augmented event. + it reads this augmented event. SQL thread does not write + Q_MASTER_DATA_WRITTEN_CODE to the slave's server binlog. */ uint32 master_data_written; From b13ed2975d2c7be450596b429020b0b91af1dbf9 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 27 Jan 2010 15:21:41 +0100 Subject: [PATCH 142/157] Bug #49210 Enable MTR timeout configuration through environment variables Define env. vars for both timeout settings This patch is for 5.0 (mtr v1) and should replaces for 5.1 up --- mysql-test/mysql-test-run.pl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index e98e05eadb1..01094f40956 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1077,13 +1077,15 @@ sub command_line_setup () { if ( ! $opt_testcase_timeout ) { - $opt_testcase_timeout= $default_testcase_timeout; + $opt_testcase_timeout= + $ENV{MTR_TESTCASE_TIMEOUT} || $default_testcase_timeout; $opt_testcase_timeout*= 10 if $opt_valgrind; } if ( ! $opt_suite_timeout ) { - $opt_suite_timeout= $default_suite_timeout; + $opt_suite_timeout= + $ENV{MTR_SUITE_TIMEOUT} || $default_suite_timeout; $opt_suite_timeout*= 6 if $opt_valgrind; } From 18761a9223f80e95356dd0a62b09a5586414d054 Mon Sep 17 00:00:00 2001 From: Staale Smedseng Date: Wed, 27 Jan 2010 16:13:39 +0100 Subject: [PATCH 143/157] Bug #49223 Change help description for mysqldump --extended-insert Help message changed to the same as in the 5.1 online documentation. --- client/mysqldump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 8a50c57201c..40e3e75cca2 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -268,7 +268,7 @@ static struct my_option my_long_options[] = (uchar**) &opt_events, (uchar**) &opt_events, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"extended-insert", 'e', - "Allows utilization of the new, much faster INSERT syntax.", + "Use multiple-row INSERT syntax that include several VALUES lists.", (uchar**) &extended_insert, (uchar**) &extended_insert, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"fields-terminated-by", OPT_FTB, From c3a73a8f6d674de1e9efcb498f3343db802d6a6c Mon Sep 17 00:00:00 2001 From: Davi Arnaut Date: Thu, 28 Jan 2010 19:51:40 -0200 Subject: [PATCH 144/157] Fix for compiler warnings: Rename method as to not hide a base. Reorder attributes initialization. Remove unused variable. Rework code to silence a warning due to assignment used as truth value. sql/item_strfunc.cc: Rename method as to not hide a base. sql/item_strfunc.h: Rename method as to not hide a base. sql/log_event.cc: Reorder attributes initialization. sql/rpl_injector.cc: Rework code to silence a warning due to assignment used as truth value. sql/rpl_record.cc: Remove unused variable. sql/sql_db.cc: Rework code to silence a warning due to assignment used as truth value. sql/sql_parse.cc: Rework code to silence a warning due to assignment used as truth value. sql/sql_table.cc: Rework code to silence a warning due to assignment used as truth value. --- sql/item_strfunc.cc | 6 +++--- sql/item_strfunc.h | 4 ++-- sql/log_event.cc | 4 ++-- sql/rpl_injector.cc | 12 ++++++------ sql/rpl_record.cc | 1 - sql/sql_db.cc | 2 +- sql/sql_parse.cc | 2 +- sql/sql_table.cc | 2 +- 8 files changed, 16 insertions(+), 17 deletions(-) diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 4cdeeef6c78..66308215d0b 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1765,19 +1765,19 @@ String *Item_func_encode::val_str(String *str) null_value= 0; res= copy_if_not_alloced(str, res, res->length()); - transform(res); + crypto_transform(res); sql_crypt.reinit(); return res; } -void Item_func_encode::transform(String *res) +void Item_func_encode::crypto_transform(String *res) { sql_crypt.encode((char*) res->ptr(),res->length()); res->set_charset(&my_charset_bin); } -void Item_func_decode::transform(String *res) +void Item_func_decode::crypto_transform(String *res) { sql_crypt.decode((char*) res->ptr(),res->length()); } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 59241872e63..5799c768162 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -363,7 +363,7 @@ public: void fix_length_and_dec(); const char *func_name() const { return "encode"; } protected: - virtual void transform(String *); + virtual void crypto_transform(String *); private: /** Provide a seed for the PRNG sequence. */ bool seed(); @@ -376,7 +376,7 @@ public: Item_func_decode(Item *a, Item *seed): Item_func_encode(a, seed) {} const char *func_name() const { return "decode"; } protected: - void transform(String *); + void crypto_transform(String *); }; diff --git a/sql/log_event.cc b/sql/log_event.cc index f03f0fa930a..2da825e63ce 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2386,8 +2386,8 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg, auto_increment_offset(thd_arg->variables.auto_increment_offset), lc_time_names_number(thd_arg->variables.lc_time_names->number), charset_database_number(0), - master_data_written(0), - table_map_for_update((ulonglong)thd_arg->table_map_for_update) + table_map_for_update((ulonglong)thd_arg->table_map_for_update), + master_data_written(0) { time_t end_time; diff --git a/sql/rpl_injector.cc b/sql/rpl_injector.cc index 666622dbac4..43f4e7d849d 100644 --- a/sql/rpl_injector.cc +++ b/sql/rpl_injector.cc @@ -114,8 +114,8 @@ int injector::transaction::write_row (server_id_type sid, table tbl, { DBUG_ENTER("injector::transaction::write_row(...)"); - int error= 0; - if (error= check_state(ROW_STATE)) + int error= check_state(ROW_STATE); + if (error) DBUG_RETURN(error); server_id_type save_id= m_thd->server_id; @@ -133,8 +133,8 @@ int injector::transaction::delete_row(server_id_type sid, table tbl, { DBUG_ENTER("injector::transaction::delete_row(...)"); - int error= 0; - if (error= check_state(ROW_STATE)) + int error= check_state(ROW_STATE); + if (error) DBUG_RETURN(error); server_id_type save_id= m_thd->server_id; @@ -152,8 +152,8 @@ int injector::transaction::update_row(server_id_type sid, table tbl, { DBUG_ENTER("injector::transaction::update_row(...)"); - int error= 0; - if (error= check_state(ROW_STATE)) + int error= check_state(ROW_STATE); + if (error) DBUG_RETURN(error); server_id_type save_id= m_thd->server_id; diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc index 1a48d0e3b0e..3a46bbcd6ee 100644 --- a/sql/rpl_record.cc +++ b/sql/rpl_record.cc @@ -382,7 +382,6 @@ int prepare_record(TABLE *const table, */ for (Field **field_ptr= table->field+skip; *field_ptr; ++field_ptr) { - uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG; Field *const f= *field_ptr; if ((f->flags & NO_DEFAULT_VALUE_FLAG) && (f->real_type() != MYSQL_TYPE_ENUM)) diff --git a/sql/sql_db.cc b/sql/sql_db.cc index d5d9830f63d..0e65f97e10b 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -828,7 +828,7 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) qinfo.db_len = strlen(db); /* These DDL methods and logging protected with LOCK_mysql_create_db */ - if (error= mysql_bin_log.write(&qinfo)) + if ((error= mysql_bin_log.write(&qinfo))) goto exit; } my_ok(thd, result); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a114d92b124..2dd71b2214a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3988,7 +3988,7 @@ end_with_restore_list: */ if (!lex->no_write_to_binlog && write_to_binlog) { - if (res= write_bin_log(thd, FALSE, thd->query(), thd->query_length())) + if ((res= write_bin_log(thd, FALSE, thd->query(), thd->query_length()))) break; } my_ok(thd); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f5df8481dc4..301ab6ceda6 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6561,7 +6561,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, thd->clear_error(); Query_log_event qinfo(thd, thd->query(), thd->query_length(), 0, FALSE, 0); - if (error= mysql_bin_log.write(&qinfo)) + if ((error= mysql_bin_log.write(&qinfo))) goto view_err_unlock; } my_ok(thd); From 443003a467ab11b2d34e8d67658338659348325b Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 29 Jan 2010 11:36:28 +0200 Subject: [PATCH 145/157] Bug #49552 : sql_buffer_result cause crash + not found records in multitable delete/subquery SQL_BUFFER_RESULT should not have an effect on non-SELECT statements according to our documentation. Fixed by not passing it through to multi-table DELETE (similarly to how it's done for multi-table UPDATE). --- mysql-test/r/delete.result | 13 +++++++++++++ mysql-test/t/delete.test | 19 ++++++++++++++++++- sql/sql_parse.cc | 4 ++-- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result index 1df19a75854..58278492985 100644 --- a/mysql-test/r/delete.result +++ b/mysql-test/r/delete.result @@ -337,3 +337,16 @@ END | DELETE IGNORE FROM t1; ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. DROP TABLE t1; +# +# Bug #49552 : sql_buffer_result cause crash + not found records +# in multitable delete/subquery +# +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1),(2),(3); +SET SESSION SQL_BUFFER_RESULT=1; +DELETE t1 FROM (SELECT SUM(a) a FROM t1) x,t1; +SET SESSION SQL_BUFFER_RESULT=DEFAULT; +SELECT * FROM t1; +a +DROP TABLE t1; +End of 5.1 tests diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test index a5dff38c078..2f51fafd6a6 100644 --- a/mysql-test/t/delete.test +++ b/mysql-test/t/delete.test @@ -357,4 +357,21 @@ END | --error ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG DELETE IGNORE FROM t1; -DROP TABLE t1; \ No newline at end of file +DROP TABLE t1; + + +--echo # +--echo # Bug #49552 : sql_buffer_result cause crash + not found records +--echo # in multitable delete/subquery +--echo # + +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES (1),(2),(3); +SET SESSION SQL_BUFFER_RESULT=1; +DELETE t1 FROM (SELECT SUM(a) a FROM t1) x,t1; + +SET SESSION SQL_BUFFER_RESULT=DEFAULT; +SELECT * FROM t1; +DROP TABLE t1; + +--echo End of 5.1 tests diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2dd71b2214a..df2c1854914 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3352,9 +3352,9 @@ end_with_restore_list: select_lex->where, 0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL, (ORDER *)NULL, - select_lex->options | thd->options | + (select_lex->options | thd->options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK | - OPTION_SETUP_TABLES_DONE, + OPTION_SETUP_TABLES_DONE) & ~OPTION_BUFFER_RESULT, del_result, unit, select_lex); res|= thd->is_error(); if (res) From 181f753e8b12c58645495622ad32b5e709120361 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Thu, 28 Jan 2010 12:10:57 +0100 Subject: [PATCH 146/157] Bug #50271: Debug output of JOIN structures is garbled sql/sql_test.cc: Assemble results of all the calls to full_name() first, in order not to garble the tabular output. --- sql/sql_test.cc | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/sql/sql_test.cc b/sql/sql_test.cc index eeb9a21b6f5..5de8301fd05 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -168,6 +168,21 @@ TEST_join(JOIN *join) uint i,ref; DBUG_ENTER("TEST_join"); + /* + Assemble results of all the calls to full_name() first, + in order not to garble the tabular output below. + */ + String ref_key_parts[MAX_TABLES]; + for (i= 0; i < join->tables; i++) + { + JOIN_TAB *tab= join->join_tab + i; + for (ref= 0; ref < tab->ref.key_parts; ref++) + { + ref_key_parts[i].append(tab->ref.items[ref]->full_name()); + ref_key_parts[i].append(" "); + } + } + DBUG_LOCK_FILE; VOID(fputs("\nInfo about JOIN\n",DBUG_FILE)); for (i=0 ; i < join->tables ; i++) @@ -199,13 +214,8 @@ TEST_join(JOIN *join) } if (tab->ref.key_parts) { - VOID(fputs(" refs: ",DBUG_FILE)); - for (ref=0 ; ref < tab->ref.key_parts ; ref++) - { - Item *item=tab->ref.items[ref]; - fprintf(DBUG_FILE,"%s ", item->full_name()); - } - VOID(fputc('\n',DBUG_FILE)); + fprintf(DBUG_FILE, + " refs: %s\n", ref_key_parts[i].ptr()); } } DBUG_UNLOCK_FILE; From 172af3722ef34876f5e33bdf63c10d46573a2864 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 29 Jan 2010 13:17:57 +0400 Subject: [PATCH 147/157] Fix for bug#49897: crash in ptr_compare when char(0) NOT NULL column is used for ORDER BY Problem: filesort isn't meant for null length sort data (e.g. char(0)), that leads to a server crash. Fix: disregard sort order if sort data record length is 0 (nothing to sort). mysql-test/r/select.result: Fix for bug#49897: crash in ptr_compare when char(0) NOT NULL column is used for ORDER BY - test result. mysql-test/t/select.test: Fix for bug#49897: crash in ptr_compare when char(0) NOT NULL column is used for ORDER BY - test case. sql/filesort.cc: Fix for bug#49897: crash in ptr_compare when char(0) NOT NULL column is used for ORDER BY - assert added as filesort cannot handle null length sort data. sql/sql_select.cc: Fix for bug#49897: crash in ptr_compare when char(0) NOT NULL column is used for ORDER BY - don't sort null length data e.g. in case of ORDER BY CHAR(0). --- mysql-test/r/select.result | 64 ++++++++++++++++++++++++++++++++++++++ mysql-test/t/select.test | 40 ++++++++++++++++++++++++ sql/filesort.cc | 2 ++ sql/sql_select.cc | 13 ++++++++ 4 files changed, 119 insertions(+) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 1b2533eec89..c13df26b2ba 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4540,4 +4540,68 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE z system NULL NULL NULL NULL 1 Warnings: Note 1003 select '2001-01-01 00:00:00' AS `a`,'2001-01-01 00:00:00' AS `a`,'2001-01-01 00:00:00' AS `a` from `test`.`t1` `x` join `test`.`t1` `y` join `test`.`t1` `z` where 1 +DROP TABLE t1; +# +# Bug #49897: crash in ptr_compare when char(0) NOT NULL +# column is used for ORDER BY +# +SET @old_sort_buffer_size= @@session.sort_buffer_size; +SET @@sort_buffer_size= 40000; +CREATE TABLE t1(a CHAR(0) NOT NULL); +INSERT INTO t1 VALUES (0), (0), (0); +INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12; +INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12; +INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12; +EXPLAIN SELECT a FROM t1 ORDER BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 +SELECT a FROM t1 ORDER BY a; +DROP TABLE t1; +CREATE TABLE t1(a CHAR(0) NOT NULL, b CHAR(0) NOT NULL, c int); +INSERT INTO t1 VALUES (0, 0, 0), (0, 0, 2), (0, 0, 1); +INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12; +INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12; +INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12; +EXPLAIN SELECT a FROM t1 ORDER BY a LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 +SELECT a FROM t1 ORDER BY a LIMIT 5; +a + + + + + +EXPLAIN SELECT * FROM t1 ORDER BY a, b LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 +SELECT * FROM t1 ORDER BY a, b LIMIT 5; +a b c + 0 + 2 + 1 + 0 + 2 +EXPLAIN SELECT * FROM t1 ORDER BY a, b, c LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 Using filesort +SELECT * FROM t1 ORDER BY a, b, c LIMIT 5; +a b c + 0 + 0 + 0 + 0 + 0 +EXPLAIN SELECT * FROM t1 ORDER BY c, a LIMIT 5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 24492 Using filesort +SELECT * FROM t1 ORDER BY c, a LIMIT 5; +a b c + 0 + 0 + 0 + 0 + 0 +SET @@sort_buffer_size= @old_sort_buffer_size; +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index eeabd2641d8..8ecadfc9dfb 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -3844,6 +3844,46 @@ EXPLAIN EXTENDED SELECT x.a, y.a, z.a FROM t1 x JOIN t1 y ON x.a=y.a JOIN t1 z ON y.a=z.a WHERE x.a='2001-01-01' AND z.a='2001-01-01 00:00:00'; +DROP TABLE t1; +--echo # +--echo # Bug #49897: crash in ptr_compare when char(0) NOT NULL +--echo # column is used for ORDER BY +--echo # +SET @old_sort_buffer_size= @@session.sort_buffer_size; +SET @@sort_buffer_size= 40000; + +CREATE TABLE t1(a CHAR(0) NOT NULL); +--disable_warnings +INSERT INTO t1 VALUES (0), (0), (0); +--enable_warnings +INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12; +INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12; +INSERT INTO t1 SELECT t11.a FROM t1 t11, t1 t12; +EXPLAIN SELECT a FROM t1 ORDER BY a; +--disable_result_log +SELECT a FROM t1 ORDER BY a; +--enable_result_log +DROP TABLE t1; + +CREATE TABLE t1(a CHAR(0) NOT NULL, b CHAR(0) NOT NULL, c int); +--disable_warnings +INSERT INTO t1 VALUES (0, 0, 0), (0, 0, 2), (0, 0, 1); +--enable_warnings +INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12; +INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12; +INSERT INTO t1 SELECT t11.a, t11.b, t11.c FROM t1 t11, t1 t12; +EXPLAIN SELECT a FROM t1 ORDER BY a LIMIT 5; +SELECT a FROM t1 ORDER BY a LIMIT 5; +EXPLAIN SELECT * FROM t1 ORDER BY a, b LIMIT 5; +SELECT * FROM t1 ORDER BY a, b LIMIT 5; +EXPLAIN SELECT * FROM t1 ORDER BY a, b, c LIMIT 5; +SELECT * FROM t1 ORDER BY a, b, c LIMIT 5; +EXPLAIN SELECT * FROM t1 ORDER BY c, a LIMIT 5; +SELECT * FROM t1 ORDER BY c, a LIMIT 5; + +SET @@sort_buffer_size= @old_sort_buffer_size; +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/filesort.cc b/sql/filesort.cc index f56e5b3a771..11be5d7f672 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -134,6 +134,8 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, error= 1; bzero((char*) ¶m,sizeof(param)); param.sort_length= sortlength(thd, sortorder, s_length, &multi_byte_charset); + /* filesort cannot handle zero-length records. */ + DBUG_ASSERT(param.sort_length); param.ref_length= table->file->ref_length; param.addon_field= 0; param.addon_length= 0; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d8ec5eff5c1..239809f1d4c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -521,13 +521,26 @@ JOIN::prepare(Item ***rref_pointer_array, if (order) { + bool real_order= FALSE; ORDER *ord; for (ord= order; ord; ord= ord->next) { Item *item= *ord->item; + /* + Disregard sort order if there's only "{VAR}CHAR(0) NOT NULL" fields + there. Such fields don't contain any data to sort. + */ + if (!real_order && + (item->type() != Item::Item::FIELD_ITEM || + ((Item_field *) item)->field->maybe_null() || + ((Item_field *) item)->field->sort_length())) + real_order= TRUE; + if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) item->split_sum_func(thd, ref_pointer_array, all_fields); } + if (!real_order) + order= NULL; } if (having && having->with_sum_func) From d468e242b300f95214e05d3aba60cc24bb2f74b3 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 29 Jan 2010 15:55:46 +0200 Subject: [PATCH 148/157] Bug #50642 : ssl certs in test suite are expiring soon. Updated the certs to expire on 2015. Made sure they work with both yassl and openssl. --- mysql-test/r/openssl_1.result | 4 +- mysql-test/std_data/cacert.pem | 24 +-- mysql-test/std_data/client-cert.pem | 83 ++++----- mysql-test/std_data/client-key.pem | 20 ++- mysql-test/std_data/server-cert.pem | 78 ++++----- mysql-test/std_data/server-key.pem | 14 +- mysql-test/std_data/server8k-cert.pem | 243 ++++++++++++-------------- mysql-test/std_data/server8k-key.pem | 194 ++++++++++---------- mysql-test/t/openssl_1.test | 4 +- 9 files changed, 317 insertions(+), 347 deletions(-) diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result index 697fa33e7c7..398202abdbe 100644 --- a/mysql-test/r/openssl_1.result +++ b/mysql-test/r/openssl_1.result @@ -3,8 +3,8 @@ create table t1(f1 int); insert into t1 values (5); grant select on test.* to ssl_user1@localhost require SSL; grant select on test.* to ssl_user2@localhost require cipher "DHE-RSA-AES256-SHA"; -grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com"; -grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB"; +grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB"; +grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB" ISSUER "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB"; grant select on test.* to ssl_user5@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "xxx"; flush privileges; connect(localhost,ssl_user5,,test,MASTER_PORT,MASTER_SOCKET); diff --git a/mysql-test/std_data/cacert.pem b/mysql-test/std_data/cacert.pem index 5473e4b153e..e44341384e4 100644 --- a/mysql-test/std_data/cacert.pem +++ b/mysql-test/std_data/cacert.pem @@ -1,17 +1,17 @@ -----BEGIN CERTIFICATE----- -MIICrTCCAhagAwIBAgIJAJXpePU0UOTVMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV +MIICrTCCAhagAwIBAgIJAMI7xZKjhrDbMA0GCSqGSIb3DQEBBAUAMEQxCzAJBgNV BAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxhMREwDwYD -VQQKEwhNeVNRTCBBQjAeFw0wOTAxMjgxMDQ5NDZaFw0xNDAxMjcxMDQ5NDZaMEQx +VQQKEwhNeVNRTCBBQjAeFw0xMDAxMjkxMTQ3MTBaFw0xNTAxMjgxMTQ3MTBaMEQx CzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxh MREwDwYDVQQKEwhNeVNRTCBBQjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA -4XQHAe5R1+TXC8noZtWf+d5E0v1C59FWpn9SWEUCBjE5UiIwuJvi4Y+7xWGOXLAI -/JzJx5gNXLBiTsE/zh0uX9fKlajLhxB0GN+QU0ZlpQ1BeYipEcNXeI/7cT499f6v -XWabnTflivdCgHSWUOQ20/Lzs6kP6/e6OoZd/DPSjPECAwEAAaOBpjCBozAdBgNV -HQ4EFgQU8uLqVWWkmuKsnZf1RWz294wRrd8wdAYDVR0jBG0wa4AU8uLqVWWkmuKs -nZf1RWz294wRrd+hSKRGMEQxCzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxh -MRAwDgYDVQQHEwdVcHBzYWxhMREwDwYDVQQKEwhNeVNRTCBBQoIJAJXpePU0UOTV -MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADgYEAMMTE5sDN+Z0ZlV7KvH3g -6+aKvql8dTpRT3hYukeQlWua0nq74WPGVw0c4e/M/vbiMwmJcCYpB9pd4+dHqzSw -aPyoenjY6UF8n7B4quWy3SIUk2LSHeJLW+kzJn2afN9gvipFhdVh/uU2TIyLGOur -Z/vmJX2W7hF1uqPnbfa8Lrw= +wQYsOEfrN4ESP3FjsI8cghE+tZVuyK2gck61lwieVxjgFMtBd65mI5a1y9pmlOI1 +yM4SB2Ppqcuw7/e1CdV1y7lvHrGNt5yqEHbN4QX1gvsN8TQauP/2WILturk4R4Hq +rKg0ZySu7f1Xhl0ed9a48LpaEHD17IcxWEGMMJwAxF0CAwEAAaOBpjCBozAMBgNV +HRMEBTADAQH/MB0GA1UdDgQWBBSvktYQ0ahLnyxyVKqty+WpBbBrDTB0BgNVHSME +bTBrgBSvktYQ0ahLnyxyVKqty+WpBbBrDaFIpEYwRDELMAkGA1UEBhMCU0UxEDAO +BgNVBAgTB1VwcHNhbGExEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FM +IEFCggkAwjvFkqOGsNswDQYJKoZIhvcNAQEEBQADgYEAdKN1PjwMHAKG2Ww1145g +JQGBnKxSFOUaoSvkBi/4ntTM+ysnViWh7WvxyWjR9zU9arfr7aqsDeQxm0XDOqzj +AQ/cQIla2/Li8tXyfc06bisH/IHRaSc2zWqioTKbEwMdVOdrvq4a8V8ic3xYyIWn +7F4WeS07J8LKardSvM0+hOA= -----END CERTIFICATE----- diff --git a/mysql-test/std_data/client-cert.pem b/mysql-test/std_data/client-cert.pem index 9300520793e..ee7f2ab281e 100644 --- a/mysql-test/std_data/client-cert.pem +++ b/mysql-test/std_data/client-cert.pem @@ -1,55 +1,46 @@ Certificate: Data: - Version: 3 (0x2) - Serial Number: 3 (0x3) - Signature Algorithm: sha1WithRSAEncryption + Version: 1 (0x0) + Serial Number: 1048577 (0x100001) + Signature Algorithm: md5WithRSAEncryption Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB Validity - Not Before: Jan 28 11:04:39 2009 GMT - Not After : Jan 28 11:04:39 2010 GMT - Subject: C=SE, ST=Uppsala, O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com + Not Before: Jan 29 11:50:22 2010 GMT + Not After : Jan 28 11:50:22 2015 GMT + Subject: C=SE, ST=Uppsala, O=MySQL AB Subject Public Key Info: Public Key Algorithm: rsaEncryption - RSA Public Key: (512 bit) - Modulus (512 bit): - 00:e1:52:30:2c:d9:be:64:28:91:5d:7a:fd:d9:e9: - 14:35:7a:d2:94:4e:91:46:e0:db:9f:6b:79:f4:4c: - ac:6e:07:61:34:86:74:62:a7:a8:44:af:fa:87:87: - a8:7d:42:61:ff:ab:50:d4:7b:bf:75:fa:d5:d5:b3: - 74:fb:56:1e:37 + Public-Key: (1024 bit) + Modulus: + 00:cc:9a:37:49:13:66:dc:cf:e3:0b:13:a1:23:ed: + 78:db:4e:bd:11:f6:8c:0d:76:f9:a3:32:56:9a:f8: + a1:21:6a:55:4e:4d:3f:e6:67:9d:26:99:b2:cd:a4: + 9a:d2:2b:59:5c:d7:8a:d3:60:68:f8:18:bd:c5:be: + 15:e1:2a:3c:a3:d4:61:cb:f5:11:94:17:81:81:f7: + 87:8c:f6:6a:d2:ee:d8:e6:77:f6:62:66:4d:2e:16: + 8d:08:81:4a:c9:c6:4b:31:e5:b9:c7:8a:84:96:48: + a7:47:8c:0d:26:90:56:4e:e6:a5:6e:8c:b3:f2:9f: + fc:3d:78:9b:49:6e:86:83:77 Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: - CA:FALSE - X509v3 Subject Key Identifier: - 58:30:B5:9B:2C:05:94:06:BA:3D:3C:F0:B2:CD:1D:67:65:E3:7F:85 - X509v3 Authority Key Identifier: - keyid:F2:E2:EA:55:65:A4:9A:E2:AC:9D:97:F5:45:6C:F6:F7:8C:11:AD:DF - DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB - serial:95:E9:78:F5:34:50:E4:D5 - - Signature Algorithm: sha1WithRSAEncryption - 05:19:e3:13:14:fc:c5:28:bf:69:f8:00:b3:25:cb:bd:ca:9f: - 2f:4c:b3:a8:04:11:f0:74:27:bd:82:2c:b4:49:9b:a7:59:f0: - f7:87:d1:e0:ba:99:a2:fe:4b:1d:10:6f:e4:a2:b3:cd:7f:8b: - 68:31:46:ee:cd:9e:e2:47:e1:4c:fa:74:d1:e2:8b:cc:a0:4b: - a8:24:d1:a4:c3:6b:2a:c6:28:cd:41:e0:06:48:e6:cf:f2:3c: - ca:37:95:d7:29:64:6b:91:91:83:e7:ac:c8:0b:87:bc:da:a6: - aa:f1:44:43:c8:74:7b:15:26:91:2e:03:c4:71:50:6c:f8:68: - dc:8c + Signature Algorithm: md5WithRSAEncryption + 5e:1f:a3:53:5f:24:13:1c:f8:28:32:b0:7f:69:69:f3:0e:c0: + 34:87:10:03:7d:da:15:8b:bd:19:b8:1a:56:31:e7:85:49:81: + c9:7f:45:20:74:3e:89:c0:e0:26:84:51:cc:04:16:ce:69:99: + 01:e1:26:99:b3:e3:f5:bd:ec:5f:a0:84:e4:38:da:75:78:7b: + 89:9c:d2:cd:60:95:20:ba:8e:e3:7c:e6:df:76:3a:7c:89:77: + 02:94:86:11:3a:c4:61:7d:6f:71:83:21:8a:17:fb:17:e2:ee: + 02:6b:61:c1:b4:52:63:d7:d8:46:b2:c5:9c:6f:38:91:8a:35: + 32:0b -----BEGIN CERTIFICATE----- -MIICfzCCAeigAwIBAgIBAzANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJTRTEQ -MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT -UUwgQUIwHhcNMDkwMTI4MTEwNDM5WhcNMTAwMTI4MTEwNDM5WjBlMQswCQYDVQQG -EwJTRTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxMTAvBgkq -hkiG9w0BCQEWImFic3RyYWN0Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb20wXDAN -BgkqhkiG9w0BAQEFAANLADBIAkEA4VIwLNm+ZCiRXXr92ekUNXrSlE6RRuDbn2t5 -9EysbgdhNIZ0YqeoRK/6h4eofUJh/6tQ1Hu/dfrV1bN0+1YeNwIDAQABo4GjMIGg -MAkGA1UdEwQCMAAwHQYDVR0OBBYEFFgwtZssBZQGuj088LLNHWdl43+FMHQGA1Ud -IwRtMGuAFPLi6lVlpJrirJ2X9UVs9veMEa3foUikRjBEMQswCQYDVQQGEwJTRTEQ -MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT -UUwgQUKCCQCV6Xj1NFDk1TANBgkqhkiG9w0BAQUFAAOBgQAFGeMTFPzFKL9p+ACz -Jcu9yp8vTLOoBBHwdCe9giy0SZunWfD3h9Hgupmi/ksdEG/korPNf4toMUbuzZ7i -R+FM+nTR4ovMoEuoJNGkw2sqxijNQeAGSObP8jzKN5XXKWRrkZGD56zIC4e82qaq -8URDyHR7FSaRLgPEcVBs+GjcjA== +MIIB5zCCAVACAxAAATANBgkqhkiG9w0BAQQFADBEMQswCQYDVQQGEwJTRTEQMA4G +A1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwg +QUIwHhcNMTAwMTI5MTE1MDIyWhcNMTUwMTI4MTE1MDIyWjAyMQswCQYDVQQGEwJT +RTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIwgZ8wDQYJKoZI +hvcNAQEBBQADgY0AMIGJAoGBAMyaN0kTZtzP4wsToSPteNtOvRH2jA12+aMyVpr4 +oSFqVU5NP+ZnnSaZss2kmtIrWVzXitNgaPgYvcW+FeEqPKPUYcv1EZQXgYH3h4z2 +atLu2OZ39mJmTS4WjQiBSsnGSzHluceKhJZIp0eMDSaQVk7mpW6Ms/Kf/D14m0lu +hoN3AgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAXh+jU18kExz4KDKwf2lp8w7ANIcQ +A33aFYu9GbgaVjHnhUmByX9FIHQ+icDgJoRRzAQWzmmZAeEmmbPj9b3sX6CE5Dja +dXh7iZzSzWCVILqO43zm33Y6fIl3ApSGETrEYX1vcYMhihf7F+LuAmthwbRSY9fY +RrLFnG84kYo1Mgs= -----END CERTIFICATE----- diff --git a/mysql-test/std_data/client-key.pem b/mysql-test/std_data/client-key.pem index 9ef464d0875..205b5f31cb9 100644 --- a/mysql-test/std_data/client-key.pem +++ b/mysql-test/std_data/client-key.pem @@ -1,9 +1,15 @@ -----BEGIN RSA PRIVATE KEY----- -MIIBOQIBAAJBAOFSMCzZvmQokV16/dnpFDV60pROkUbg259refRMrG4HYTSGdGKn -qESv+oeHqH1CYf+rUNR7v3X61dWzdPtWHjcCAwEAAQJAXYooM8ZlcuEgj+VKU1ee -qyEFIMqJJxqcMk+E/nWCM96WxCP3zHNSrqNfSpI3ld7QzMwhdRz+gFLxT2gGNpIw -MQIhAPxzM/lDihe67X3ADYtDl9ZjA8Pm430x9sXlcxI17tCZAiEA5H1SyFl4mUee -9VnfSC2XGW7lwz72ZygfVX+b7tLWF08CIEh40gzW5MfXM+KLxdea+fXjyursV5ZT -R6KcMiKiNQLRAiAcmHqlzFzFgisotai2Fc6VRkXHG7gmzOSvBJt1VjmpDQIge6jf -2N7whTdvC4ferB+zUlgWQdyvx1c3T4gnt6PYdaY= +MIICXQIBAAKBgQDMmjdJE2bcz+MLE6Ej7XjbTr0R9owNdvmjMlaa+KEhalVOTT/m +Z50mmbLNpJrSK1lc14rTYGj4GL3FvhXhKjyj1GHL9RGUF4GB94eM9mrS7tjmd/Zi +Zk0uFo0IgUrJxksx5bnHioSWSKdHjA0mkFZO5qVujLPyn/w9eJtJboaDdwIDAQAB +AoGASqk/4We2En+93y3jkIO4pXafIe3w/3zZ7caRue1ehx4RUQh5d+95djuB9u7J +HEZ7TpjM7QNyao5EueL6gvbxt0LXFvqAMni7yM9tt/HUYtHHPqYiRtUny9bKYFTm +l8szCCMal/wD9GZU9ByHDNHm7tHUMyMhARNTYSgx+SERFmECQQD/6jJocC4SXf6f +T3LqimWR02lbJ7qCoDgRglsUXh0zjrG+IIiAyE+QOCCx1GMe3Uw6bsIuYwdHT6as +WcdPs04xAkEAzKulvEvLVvN5zfa/DTYRTV7jh6aDleOxjsD5oN/oJXoACnPzVuUL +qQQMNtuAXm6Q1QItrRxpQsSKbY0UQka6JwJBAOSgoNoG5lIIYTKIMvzwGV+XBLeo +HYsXgh+6Wo4uql3mLErUG78ZtWL9kc/tE4R+ZdyKGLaCR/1gXmH5bwN4B/ECQEBb +uUH8k3REG4kojesZlVc+/00ojzgS4UKCa/yqa9VdB6ZBz8MDQydinnShkTwgiGpy +xOoqhO753o2UT0qH8wECQQC99IEJWUnwvExVMkLaZH5NjAFJkb22sjkmuT11tAgU +RQgOMoDOm6driojnOnDWOkx1r1Gy9NgMLooduja4v6cx -----END RSA PRIVATE KEY----- diff --git a/mysql-test/std_data/server-cert.pem b/mysql-test/std_data/server-cert.pem index cab54db8b23..5922fe7ded7 100644 --- a/mysql-test/std_data/server-cert.pem +++ b/mysql-test/std_data/server-cert.pem @@ -1,55 +1,41 @@ Certificate: Data: - Version: 3 (0x2) - Serial Number: 1 (0x1) - Signature Algorithm: sha1WithRSAEncryption + Version: 1 (0x0) + Serial Number: 1048578 (0x100002) + Signature Algorithm: md5WithRSAEncryption Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB Validity - Not Before: Jan 28 10:55:13 2009 GMT - Not After : Jan 28 10:55:13 2010 GMT - Subject: C=SE, ST=Uppsala, O=MySQL AB, CN=localhost/emailAddress=abstract.mysql.developer@mysql.com + Not Before: Jan 29 11:56:49 2010 GMT + Not After : Jan 28 11:56:49 2015 GMT + Subject: C=SE, ST=Uppsala, O=MySQL AB, CN=localhost Subject Public Key Info: Public Key Algorithm: rsaEncryption - RSA Public Key: (512 bit) - Modulus (512 bit): - 00:b6:8f:e5:b7:b4:86:83:13:8a:f9:bf:63:cb:64: - 2d:b9:51:d1:de:ab:7b:45:1f:aa:b5:66:73:13:f9: - a6:07:d5:ba:7c:fa:92:bd:37:e2:ad:87:db:3e:b6: - 6a:12:64:f8:ee:17:e3:15:06:2f:a8:82:68:bf:57: - 8d:c3:04:98:27 + Public-Key: (512 bit) + Modulus: + 00:cd:e4:87:51:9d:72:11:a0:d1:fa:f3:92:8b:13: + 1c:eb:f7:e2:9a:2f:72:a8:d6:65:48:d1:69:af:1b: + c0:4c:13:e5:60:60:51:41:e9:ab:a6:bc:13:bb:0c: + 5e:32:7c:d9:6c:9e:cd:05:24:84:78:db:80:91:2e: + d8:88:2b:c2:ed Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: - CA:FALSE - X509v3 Subject Key Identifier: - D9:9A:B8:5F:22:EA:04:10:C8:25:7D:82:57:E6:2E:FD:19:29:E7:DA - X509v3 Authority Key Identifier: - keyid:F2:E2:EA:55:65:A4:9A:E2:AC:9D:97:F5:45:6C:F6:F7:8C:11:AD:DF - DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB - serial:95:E9:78:F5:34:50:E4:D5 - - Signature Algorithm: sha1WithRSAEncryption - 54:07:2d:21:0b:a5:af:3b:58:23:32:5e:56:7f:ab:58:63:48: - 91:aa:38:90:89:16:f9:cc:bf:a4:0e:78:2b:9f:c5:1b:58:a6: - e6:08:8f:2e:ae:97:03:21:9b:f1:cd:c0:26:8f:1d:d7:28:27: - a0:8e:81:09:1b:1c:0f:c9:a5:41:3a:2d:44:3f:9c:fa:87:ff: - c8:4c:2b:44:f7:1b:c1:3e:4f:01:7f:e9:26:cc:9f:1c:06:b5: - 0b:27:d1:10:90:be:93:0c:9c:e7:b0:d1:ea:27:99:4e:06:14: - 0c:7a:e9:c1:52:c5:33:68:bc:61:0d:db:81:3b:57:48:57:bf: - 42:9a + Signature Algorithm: md5WithRSAEncryption + 73:ce:9c:6e:39:46:b4:14:be:da:3f:f3:1b:ba:90:bc:23:43: + d7:82:2a:70:4e:a6:d9:5a:65:5c:b7:df:71:df:75:77:c5:80: + a4:af:fa:d2:59:e2:fd:c9:9c:f0:98:95:8e:69:a9:8c:7c:d8: + 6f:48:d2:e3:36:e0:cd:ff:3f:d1:a5:e6:ab:75:09:c4:50:10: + c4:96:dd:bf:3b:de:32:46:da:ca:4a:f1:d6:52:8a:33:2f:ab: + f5:2e:70:3f:d4:9c:be:00:c8:03:f9:39:8a:df:5b:70:3c:40: + ef:03:be:7c:3d:1d:32:32:f3:51:81:e2:83:30:6e:3d:38:9b: + fb:3c -----BEGIN CERTIFICATE----- -MIICkzCCAfygAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJTRTEQ -MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT -UUwgQUIwHhcNMDkwMTI4MTA1NTEzWhcNMTAwMTI4MTA1NTEzWjB5MQswCQYDVQQG -EwJTRTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxEjAQBgNV -BAMTCWxvY2FsaG9zdDExMC8GCSqGSIb3DQEJARYiYWJzdHJhY3QubXlzcWwuZGV2 -ZWxvcGVyQG15c3FsLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC2j+W3tIaD -E4r5v2PLZC25UdHeq3tFH6q1ZnMT+aYH1bp8+pK9N+Kth9s+tmoSZPjuF+MVBi+o -gmi/V43DBJgnAgMBAAGjgaMwgaAwCQYDVR0TBAIwADAdBgNVHQ4EFgQU2Zq4XyLq -BBDIJX2CV+Yu/Rkp59owdAYDVR0jBG0wa4AU8uLqVWWkmuKsnZf1RWz294wRrd+h -SKRGMEQxCzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMRAwDgYDVQQHEwdV -cHBzYWxhMREwDwYDVQQKEwhNeVNRTCBBQoIJAJXpePU0UOTVMA0GCSqGSIb3DQEB -BQUAA4GBAFQHLSELpa87WCMyXlZ/q1hjSJGqOJCJFvnMv6QOeCufxRtYpuYIjy6u -lwMhm/HNwCaPHdcoJ6COgQkbHA/JpUE6LUQ/nPqH/8hMK0T3G8E+TwF/6SbMnxwG -tQsn0RCQvpMMnOew0eonmU4GFAx66cFSxTNovGEN24E7V0hXv0Ka +MIIBtzCCASACAxAAAjANBgkqhkiG9w0BAQQFADBEMQswCQYDVQQGEwJTRTEQMA4G +A1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwg +QUIwHhcNMTAwMTI5MTE1NjQ5WhcNMTUwMTI4MTE1NjQ5WjBGMQswCQYDVQQGEwJT +RTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxEjAQBgNVBAMT +CWxvY2FsaG9zdDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDN5IdRnXIRoNH685KL +Exzr9+KaL3Ko1mVI0WmvG8BME+VgYFFB6aumvBO7DF4yfNlsns0FJIR424CRLtiI +K8LtAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAc86cbjlGtBS+2j/zG7qQvCND14Iq +cE6m2VplXLffcd91d8WApK/60lni/cmc8JiVjmmpjHzYb0jS4zbgzf8/0aXmq3UJ +xFAQxJbdvzveMkbaykrx1lKKMy+r9S5wP9ScvgDIA/k5it9bcDxA7wO+fD0dMjLz +UYHigzBuPTib+zw= -----END CERTIFICATE----- diff --git a/mysql-test/std_data/server-key.pem b/mysql-test/std_data/server-key.pem index 0d8274b77f6..1083495cb96 100644 --- a/mysql-test/std_data/server-key.pem +++ b/mysql-test/std_data/server-key.pem @@ -1,9 +1,9 @@ -----BEGIN RSA PRIVATE KEY----- -MIIBOQIBAAJBALaP5be0hoMTivm/Y8tkLblR0d6re0UfqrVmcxP5pgfVunz6kr03 -4q2H2z62ahJk+O4X4xUGL6iCaL9XjcMEmCcCAwEAAQJASA5VwgNb0CKHiPm0ntOk -hG+54SRX3DmafEy6gRjZIl/bZ/asSLhXUZ+CeohyrQh7BZgYWvykd8pRISL9eKsU -GQIhAOXkUrOtP/EtjyqNluEqZdG+RZi/7p61JS3Ce13Myu+LAiEAy0uMlV34AJpM -b40FPKqlHxw8DD/Dt1iKhNVAg8+LDVUCIFjv7fbJDbW2VG63/Cj8CAwOukoP5rbL -iaicVrHBKrllAiB9+MiaXeopZXNrxDS0jQFYr8Q9yt1aJVFgUkxx4Q9HKQIgZPs0 -KlF3NNNWw78INaAEkyf0IEssnLMsuoCWw0DIOak= +MIIBOwIBAAJBAM3kh1GdchGg0frzkosTHOv34povcqjWZUjRaa8bwEwT5WBgUUHp +q6a8E7sMXjJ82WyezQUkhHjbgJEu2Igrwu0CAwEAAQJBAJuwhFbF3NzRpBbEmnqJ +4GPa1UJMQMLFJF+04tqj/HxJcAIVhOJhGmmtYNw1yjz/ZsPnfJCMz4eFOtdjvGtf +peECIQDmFFg2WLvYo+2m9w9V7z4ZIkg7ixYkI/ObUUctfZkPOQIhAOUWnrvjFrAX +bIvYT/YR50+3ZDLEc51XxNgJnWqWYl1VAiEAnTOFWgyivFC1DgF8PvDp8u5TgCt2 +A1d1GMgd490O+TECIC/WMl0/hTxOF9930vKqOGf//o9PUGkZq8QE9fcM4gtlAiAE +iOcFpnLjtWj57jrhuw214ucnB5rklkQQe+AtcARNkg== -----END RSA PRIVATE KEY----- diff --git a/mysql-test/std_data/server8k-cert.pem b/mysql-test/std_data/server8k-cert.pem index 3b86effd699..06e118cf034 100644 --- a/mysql-test/std_data/server8k-cert.pem +++ b/mysql-test/std_data/server8k-cert.pem @@ -1,138 +1,125 @@ Certificate: Data: - Version: 3 (0x2) - Serial Number: 4 (0x4) - Signature Algorithm: sha1WithRSAEncryption + Version: 1 (0x0) + Serial Number: 1048579 (0x100003) + Signature Algorithm: md5WithRSAEncryption Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB Validity - Not Before: Jan 28 11:12:27 2009 GMT - Not After : Jan 28 11:12:27 2010 GMT + Not Before: Jan 29 12:01:53 2010 GMT + Not After : Jan 28 12:01:53 2015 GMT Subject: C=SE, ST=Uppsala, O=MySQL AB, CN=server Subject Public Key Info: Public Key Algorithm: rsaEncryption - RSA Public Key: (8192 bit) - Modulus (8192 bit): - 00:c0:8f:22:03:24:59:67:46:14:d6:8f:60:09:58: - 06:07:45:f1:78:71:55:f1:ea:b9:30:8a:cd:c3:3c: - b9:bf:65:6e:18:ed:a0:b8:c9:19:56:6f:c4:90:19: - c8:65:09:db:ff:bf:82:a1:08:ad:01:4f:5a:a3:d4: - 3d:78:7e:4b:4a:01:a4:7d:e8:7b:05:3e:7d:d8:b9: - 55:58:60:d6:1c:ce:e8:32:62:2c:19:60:f3:ed:05: - 99:6d:c9:77:07:2e:11:6d:0b:9a:c7:68:38:46:e8: - fa:31:80:df:e8:79:f0:f1:fd:a9:94:c3:fa:0d:f5: - 78:ac:49:7e:d5:17:fd:e1:ee:44:f3:c7:0e:30:32: - 5d:a9:19:25:e4:bb:21:1d:fe:3c:84:48:40:f5:58: - f4:bf:13:8c:85:68:bb:ec:f5:dd:c6:38:d1:b0:77: - 1f:a6:8e:4f:8d:e2:6f:49:74:f5:3f:90:65:8e:99: - 1e:59:9c:1c:b5:26:24:c4:b1:de:1e:fb:96:65:c4: - 31:14:1a:53:b8:5e:62:8a:c7:04:f7:b4:36:a4:af: - 07:c8:27:06:ed:dd:e6:f4:8c:62:f1:65:40:d0:9f: - 9f:a9:14:c8:8e:8b:74:d6:67:5a:d0:c9:4d:35:a1: - d5:7b:39:3a:42:9f:e4:d0:f4:c6:0f:2e:42:30:4b: - 56:b2:3d:6d:8e:2d:58:c5:69:99:35:49:95:95:99: - b6:87:29:2b:32:d1:50:08:cd:25:14:48:6d:10:99: - 85:61:3c:41:26:21:55:cc:1f:cf:ad:b0:2f:b9:89: - d8:4e:a0:18:ff:75:1d:b6:97:7c:c5:fa:8b:dc:93: - 17:86:0a:64:d4:09:35:d5:83:34:6d:5c:6d:c6:8c: - cd:b9:ec:c2:93:c6:c1:b7:cc:04:6f:22:e0:07:bf: - e0:d9:9b:2f:d5:a0:50:cc:f9:f0:95:83:8f:f4:30: - 83:72:94:d7:b5:4b:da:cc:9f:54:3b:8d:78:77:0b: - 24:6c:0f:c2:96:61:96:2f:b8:5f:b5:7a:ab:7a:5b: - 97:7a:a9:ad:40:8b:f2:d6:c6:8d:81:d9:94:61:8f: - 9d:03:c5:b9:10:03:68:83:bf:04:81:cc:ac:bd:34: - 89:e8:d4:8d:43:20:e2:b6:a4:11:3d:15:2a:82:0c: - d6:3a:6a:8c:62:d4:93:bc:c3:80:bf:1b:b4:2b:0a: - 7a:34:f0:cd:1e:82:3f:25:0f:d1:04:a8:0a:05:19: - b0:d6:16:83:39:af:0b:45:7d:cb:14:7e:4d:aa:aa: - c2:39:a8:46:38:ab:bd:ab:2a:bd:34:43:7f:da:25: - de:2b:fb:69:3b:fe:3b:87:fd:98:94:76:4a:bf:04: - a3:31:e3:3a:ff:6f:04:fa:fa:24:e4:2a:89:e9:0e: - bf:44:4c:72:85:82:3c:89:4a:03:63:01:41:92:53: - d0:82:60:6e:d8:ff:8c:a2:b4:1a:3b:20:6d:ae:74: - 92:30:4e:48:e3:51:a6:cb:73:97:06:13:03:32:23: - 9b:7d:a2:c7:3a:a9:af:97:8c:51:ed:fe:fa:b4:b4: - 1a:a3:87:fc:cf:8c:8e:e6:80:15:03:fd:fe:7d:bd: - b1:76:f1:5f:b3:09:2b:4c:4d:a7:7c:b5:72:b1:d6: - db:38:c0:67:a4:54:bc:87:09:a5:39:ba:1a:7e:3f: - 74:60:ad:3d:4b:be:94:53:f3:64:16:c7:33:35:ec: - 41:00:95:b6:de:99:62:a2:7a:28:9a:45:4d:fa:cd: - a6:77:f6:de:58:72:50:c8:7d:69:38:db:07:04:84: - d8:4d:39:f7:50:13:43:ae:2d:af:45:a4:2a:39:56: - 3c:b8:b7:d8:26:a4:36:c9:23:aa:aa:b8:49:0b:21: - ba:9e:7a:2b:7f:4d:29:9f:0e:00:1e:b4:5e:a6:fa: - 49:fe:8d:e5:74:57:d8:ba:d9:92:2c:d2:ac:84:1d: - f2:a6:a4:44:1c:bf:88:41:32:7e:d1:c3:2f:6e:bc: - 0f:5d:19:a6:8f:74:2b:67:ba:dd:a9:db:68:b5:ce: - 9d:25:48:df:54:08:d0:1d:4f:2e:5b:24:bc:05:0f: - fb:58:46:fa:02:ca:53:93:29:cf:10:27:c2:a0:18: - d0:f5:d4:b9:3c:5e:df:8e:6c:f5:7c:b9:b4:54:cc: - 39:16:5d:3c:da:96:b3:c3:6c:d4:70:5d:d3:30:a7: - a6:bd:6f:dd:41:bc:a8:de:42:60:59:9a:85:25:0d: - 2a:45:c3:05:b4:6e:7a:4a:4d:ca:8c:0a:e5:6c:34: - bc:20:9b:6d:4a:ca:ca:b6:a6:3a:a0:db:c3:0e:20: - 1a:12:1b:77:dd:cb:1d:7f:c3:0d:0d:e7:c1:fd:96: - d2:c7:68:80:99:a0:d9:8a:33:21:a3:8b:a2:5a:a7: - 7e:27:06:02:7f:ed:60:11:37:34:54:17:7f:4d:90: - 14:1e:69:37:0d:ba:f0:2b:f0:a3:2d:62:79:c8:76: - a8:ea:c8:e7:3b:1f:c6:4f:c2:0c:d7:ac:f0:77:53: - 5d:f0:50:b4:df:9b:03:ca:4d:41:e1:18:b2:25:30: - 86:1d:63:e5:67:b1:53:cd:6b:4e:83:1a:b9:5e:2d: - 05:15:6b:d4:8e:b1:97:fc:31:03:57:cb:bf:27:7f: - cd:5f:27:7e:66:e7:3c:17:09:b6:11:2a:4f:33:cd: - eb:1a:d3:6f:d5:15:8b:8b:ce:68:6b:7e:9a:95:e5: - 74:7f:17:57:d9 + Public-Key: (8192 bit) + Modulus: + 00:ca:aa:1d:c4:11:ec:91:f0:c7:ff:5f:90:92:fc: + 40:0c:5e:b7:3d:00:c5:20:d5:0f:89:31:07:d7:41: + 4c:8b:60:80:aa:38:14:de:93:6b:9c:74:88:41:68: + b5:02:41:01:2d:86:a2:7a:95:53:5e:7b:67:2f:6c: + 1e:29:51:f9:44:fd:4a:80:be:b2:23:a1:3e:1b:38: + cf:88:c4:71:ee:f8:6b:41:c5:2d:c0:c3:52:ac:59: + 7d:81:34:19:95:32:b8:9a:51:b6:41:36:d4:c4:a1: + ae:84:e6:38:b9:e8:bf:96:be:19:7a:6b:77:4d:e0: + de:e6:b3:b6:6b:bc:3d:dd:68:bc:4b:c4:eb:f5:36: + 93:ed:56:a2:15:50:8a:10:e8:d6:22:ed:6c:b1:cd: + c3:18:c9:f6:0a:e1:de:61:65:62:d6:14:41:8c:b5: + fb:14:68:c1:cf:12:5d:41:21:9d:57:11:43:7d:bb: + 43:2c:21:bb:c3:44:7d:a8:cf:1f:c3:71:75:b5:47: + c2:7d:ce:38:3c:73:64:9e:15:d8:a7:27:cf:bd:40: + c8:45:08:e3:c8:39:a8:0b:8e:c2:5b:7b:f1:47:91: + 12:91:cc:e1:00:e0:94:5b:bd:32:e4:0c:8d:c3:be: + cc:76:32:52:12:69:b0:18:e0:b0:c2:76:34:5a:5f: + 79:d9:f6:81:9d:02:0a:61:69:1c:33:ce:49:fa:76: + 03:1e:07:5b:27:0b:bf:34:9e:34:96:b8:03:9b:50: + 3a:6a:2f:17:7a:14:cf:65:63:00:37:52:a8:73:ce: + 4b:14:40:f4:d2:9a:56:54:33:b8:77:2e:42:5b:8f: + ec:1f:18:f4:ad:ab:8a:4a:8d:6d:70:25:f3:58:e7: + cb:66:51:14:7d:16:f4:eb:6d:56:76:76:51:6e:d6: + 1d:da:d3:8d:c0:64:5a:67:4e:af:e2:bf:33:d1:b8: + f6:2a:fc:57:87:a7:35:5e:80:c9:ac:fc:87:c9:71: + 17:91:bf:b7:4d:a3:ed:3c:1b:27:f4:66:a0:f9:46: + 03:27:cc:ea:80:f6:4b:40:f6:41:94:cd:bd:0a:b3: + ef:26:be:de:6f:69:ae:0f:3f:1c:55:63:33:90:9b: + ed:ca:5a:12:4d:de:4b:06:c2:a2:92:b0:42:3d:31: + af:a4:15:12:15:f8:8a:e9:88:8d:cf:fd:85:66:50: + 6f:11:f1:9f:48:f3:b5:ba:9d:86:68:24:a2:5d:a8: + 7c:54:42:fa:d8:b5:c5:f2:dd:0e:0f:d0:68:e4:54: + 7e:c5:b9:a0:9b:65:2d:77:f4:8f:b9:30:0a:d5:86: + 5c:ed:c9:7c:d1:da:9d:0d:63:50:ee:e5:1e:92:63: + cc:a2:0c:e8:4a:96:02:4d:dc:8f:df:7c:8f:08:18: + a8:30:88:d7:af:89:ad:fc:57:4b:10:f9:f1:cb:48: + e8:b6:3b:c8:3f:fc:c2:d3:d1:4a:10:3c:1b:6b:64: + dc:e5:65:1e:5b:b2:da:b1:e2:24:97:8f:ee:c0:4b: + 8e:18:83:7c:17:a6:3c:45:b3:60:06:23:f2:2f:18: + 13:9e:17:8a:c6:72:79:8c:4d:04:f3:9d:ea:e0:25: + d3:33:8c:1e:11:47:63:1f:a5:45:3f:bd:85:b3:fe: + a5:68:ee:48:b7:0c:a4:c9:7f:72:d0:75:66:9b:6a: + f9:a0:50:f3:a8:59:6d:a3:dd:38:4f:70:2b:bb:ff: + 92:2e:71:ab:ef:e9:00:ed:0d:d1:b4:6f:f0:8e:b2: + 09:fb:4d:61:0d:d9:10:d5:54:11:cd:03:94:84:fd: + a8:68:e4:45:6e:1e:6a:1e:2f:85:a1:6d:f5:b6:c0: + f1:ee:f7:36:e9:fe:c2:f7:ad:cc:13:46:5b:88:42: + f0:2d:1f:b5:0e:7e:b5:2b:e4:8d:ab:b9:87:30:6a: + 3d:12:f4:ad:f3:1c:ac:cc:1a:48:29:2a:96:7b:80: + 00:0b:6e:59:87:bf:a3:ca:70:99:1b:1c:fd:72:3d: + b2:d3:94:4a:cf:55:75:be:1f:40:ec:55:35:48:2d: + 55:f0:00:da:3c:b0:60:ba:11:32:66:54:0b:be:06: + a4:5e:b7:c9:59:bb:4d:f4:92:06:26:48:6e:c2:12: + d4:7c:f0:20:b8:a2:e1:bc:6a:b6:19:0e:37:47:55: + c9:f2:49:0d:96:75:a2:84:64:bf:34:fc:be:b2:41: + e4:f5:88:eb:e1:b7:26:a5:e5:41:c2:20:0c:f6:e2: + a8:a5:e7:76:54:a5:fb:4b:80:05:7d:18:85:7a:ba: + bc:b7:ad:c0:2f:60:85:cc:15:12:1c:2f:0a:9e:f3: + 7c:40:cf:f4:3e:23:d2:95:ca:d0:06:58:52:f0:84: + d8:0f:3d:eb:ff:12:68:94:79:8f:be:40:29:5f:98: + c8:90:6c:05:2f:99:8c:2a:63:78:1f:23:b1:29:c5: + e7:49:c9:b2:92:0f:53:0b:d5:71:28:17:c2:19:bf: + 60:bf:7c:87:a8:ab:c1:f4:0a:c1:b8:d2:68:ee:c1: + ce:a7:13:13:17:6d:24:5d:a2:37:a6:d7:7d:48:8b: + 2b:74:2d:40:2e:ca:19:d5:b6:3e:6c:42:71:fa:cf: + 85:87:f9:de:80:73:8b:89:f4:70:f0:d8:d7:ff:40: + 41:9c:c7:15:6d:9b:6e:4c:b5:52:02:99:79:32:73: + ca:26:a0:ac:31:6f:c4:b0:f5:da:bb:c2:1f:e0:9f: + 44:ba:25:f7:9f Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: - CA:FALSE - X509v3 Subject Key Identifier: - 58:12:24:59:A7:3C:29:15:89:5A:C2:12:DB:E7:A5:42:10:21:B7:BA - X509v3 Authority Key Identifier: - keyid:F2:E2:EA:55:65:A4:9A:E2:AC:9D:97:F5:45:6C:F6:F7:8C:11:AD:DF - DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB - serial:95:E9:78:F5:34:50:E4:D5 - - Signature Algorithm: sha1WithRSAEncryption - cd:cb:5c:83:35:ea:cb:cb:c3:a8:c3:95:e2:e6:6f:4d:d8:e4: - ee:41:dd:3f:35:82:ac:2f:fd:63:89:4f:3a:19:d7:81:75:b3: - a3:fc:36:b2:12:d5:c6:56:bc:13:60:37:33:6e:a0:d8:ae:7c: - 88:f9:4b:ee:7b:1f:c8:f0:56:19:07:4d:bb:45:52:1c:78:81: - 07:7c:13:86:b8:86:70:85:e4:71:25:58:78:d1:be:de:22:82: - 6d:1a:4b:06:ac:f0:e8:50:87:c7:69:64:c2:61:43:cd:96:06: - a6:7e:09:a9:02:01:2a:a2:40:f3:cd:10:80:48:d0:34:55:40: - b9:ce + Signature Algorithm: md5WithRSAEncryption + 08:75:dc:b9:3f:aa:b6:7e:81:7a:39:d1:ee:ed:44:b6:ce:1b: + 37:c4:4c:19:d0:66:e6:eb:b5:4f:2a:ef:95:58:64:21:55:01: + 12:30:ac:8a:95:d1:06:de:29:46:a4:f1:7d:7f:b0:1e:d2:4e: + fb:f6:fa:9a:74:be:85:62:db:0b:82:90:58:62:c5:5f:f1:80: + 02:9f:c5:fb:f3:6b:b0:b4:3b:04:b1:e5:53:c2:d0:00:a1:1a: + 9d:65:60:6f:73:98:67:e0:9c:c8:12:94:79:59:bf:43:7b:f5: + 77:c8:8f:df:b1:cd:11:1c:01:19:99:c2:22:42:f7:41:ae:b4: + b8:1a -----BEGIN CERTIFICATE----- -MIIGJTCCBY6gAwIBAgIBBDANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJTRTEQ -MA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlT -UUwgQUIwHhcNMDkwMTI4MTExMjI3WhcNMTAwMTI4MTExMjI3WjBDMQswCQYDVQQG -EwJTRTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxDzANBgNV -BAMTBnNlcnZlcjCCBCIwDQYJKoZIhvcNAQEBBQADggQPADCCBAoCggQBAMCPIgMk -WWdGFNaPYAlYBgdF8XhxVfHquTCKzcM8ub9lbhjtoLjJGVZvxJAZyGUJ2/+/gqEI -rQFPWqPUPXh+S0oBpH3oewU+fdi5VVhg1hzO6DJiLBlg8+0FmW3JdwcuEW0Lmsdo -OEbo+jGA3+h58PH9qZTD+g31eKxJftUX/eHuRPPHDjAyXakZJeS7IR3+PIRIQPVY -9L8TjIVou+z13cY40bB3H6aOT43ib0l09T+QZY6ZHlmcHLUmJMSx3h77lmXEMRQa -U7heYorHBPe0NqSvB8gnBu3d5vSMYvFlQNCfn6kUyI6LdNZnWtDJTTWh1Xs5OkKf -5ND0xg8uQjBLVrI9bY4tWMVpmTVJlZWZtocpKzLRUAjNJRRIbRCZhWE8QSYhVcwf -z62wL7mJ2E6gGP91HbaXfMX6i9yTF4YKZNQJNdWDNG1cbcaMzbnswpPGwbfMBG8i -4Ae/4NmbL9WgUMz58JWDj/Qwg3KU17VL2syfVDuNeHcLJGwPwpZhli+4X7V6q3pb -l3qprUCL8tbGjYHZlGGPnQPFuRADaIO/BIHMrL00iejUjUMg4rakET0VKoIM1jpq -jGLUk7zDgL8btCsKejTwzR6CPyUP0QSoCgUZsNYWgzmvC0V9yxR+TaqqwjmoRjir -vasqvTRDf9ol3iv7aTv+O4f9mJR2Sr8EozHjOv9vBPr6JOQqiekOv0RMcoWCPIlK -A2MBQZJT0IJgbtj/jKK0Gjsgba50kjBOSONRpstzlwYTAzIjm32ixzqpr5eMUe3+ -+rS0GqOH/M+MjuaAFQP9/n29sXbxX7MJK0xNp3y1crHW2zjAZ6RUvIcJpTm6Gn4/ -dGCtPUu+lFPzZBbHMzXsQQCVtt6ZYqJ6KJpFTfrNpnf23lhyUMh9aTjbBwSE2E05 -91ATQ64tr0WkKjlWPLi32CakNskjqqq4SQshup56K39NKZ8OAB60Xqb6Sf6N5XRX -2LrZkizSrIQd8qakRBy/iEEyftHDL268D10Zpo90K2e63anbaLXOnSVI31QI0B1P -LlskvAUP+1hG+gLKU5MpzxAnwqAY0PXUuTxe345s9Xy5tFTMORZdPNqWs8Ns1HBd -0zCnpr1v3UG8qN5CYFmahSUNKkXDBbRuekpNyowK5Ww0vCCbbUrKyramOqDbww4g -GhIbd93LHX/DDQ3nwf2W0sdogJmg2YozIaOLolqnficGAn/tYBE3NFQXf02QFB5p -Nw268Cvwoy1iech2qOrI5zsfxk/CDNes8HdTXfBQtN+bA8pNQeEYsiUwhh1j5Wex -U81rToMauV4tBRVr1I6xl/wxA1fLvyd/zV8nfmbnPBcJthEqTzPN6xrTb9UVi4vO -aGt+mpXldH8XV9kCAwEAAaOBozCBoDAJBgNVHRMEAjAAMB0GA1UdDgQWBBRYEiRZ -pzwpFYlawhLb56VCECG3ujB0BgNVHSMEbTBrgBTy4upVZaSa4qydl/VFbPb3jBGt -36FIpEYwRDELMAkGA1UEBhMCU0UxEDAOBgNVBAgTB1VwcHNhbGExEDAOBgNVBAcT -B1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCggkAlel49TRQ5NUwDQYJKoZIhvcN -AQEFBQADgYEAzctcgzXqy8vDqMOV4uZvTdjk7kHdPzWCrC/9Y4lPOhnXgXWzo/w2 -shLVxla8E2A3M26g2K58iPlL7nsfyPBWGQdNu0VSHHiBB3wThriGcIXkcSVYeNG+ -3iKCbRpLBqzw6FCHx2lkwmFDzZYGpn4JqQIBKqJA880QgEjQNFVAuc4= +MIIFfDCCBOUCAxAAAzANBgkqhkiG9w0BAQQFADBEMQswCQYDVQQGEwJTRTEQMA4G +A1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwg +QUIwHhcNMTAwMTI5MTIwMTUzWhcNMTUwMTI4MTIwMTUzWjBDMQswCQYDVQQGEwJT +RTEQMA4GA1UECBMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxDzANBgNVBAMT +BnNlcnZlcjCCBCIwDQYJKoZIhvcNAQEBBQADggQPADCCBAoCggQBAMqqHcQR7JHw +x/9fkJL8QAxetz0AxSDVD4kxB9dBTItggKo4FN6Ta5x0iEFotQJBAS2GonqVU157 +Zy9sHilR+UT9SoC+siOhPhs4z4jEce74a0HFLcDDUqxZfYE0GZUyuJpRtkE21MSh +roTmOLnov5a+GXprd03g3uaztmu8Pd1ovEvE6/U2k+1WohVQihDo1iLtbLHNwxjJ +9grh3mFlYtYUQYy1+xRowc8SXUEhnVcRQ327Qywhu8NEfajPH8NxdbVHwn3OODxz +ZJ4V2Kcnz71AyEUI48g5qAuOwlt78UeREpHM4QDglFu9MuQMjcO+zHYyUhJpsBjg +sMJ2NFpfedn2gZ0CCmFpHDPOSfp2Ax4HWycLvzSeNJa4A5tQOmovF3oUz2VjADdS +qHPOSxRA9NKaVlQzuHcuQluP7B8Y9K2rikqNbXAl81jny2ZRFH0W9OttVnZ2UW7W +HdrTjcBkWmdOr+K/M9G49ir8V4enNV6Ayaz8h8lxF5G/t02j7TwbJ/RmoPlGAyfM +6oD2S0D2QZTNvQqz7ya+3m9prg8/HFVjM5Cb7cpaEk3eSwbCopKwQj0xr6QVEhX4 +iumIjc/9hWZQbxHxn0jztbqdhmgkol2ofFRC+ti1xfLdDg/QaORUfsW5oJtlLXf0 +j7kwCtWGXO3JfNHanQ1jUO7lHpJjzKIM6EqWAk3cj998jwgYqDCI16+JrfxXSxD5 +8ctI6LY7yD/8wtPRShA8G2tk3OVlHluy2rHiJJeP7sBLjhiDfBemPEWzYAYj8i8Y +E54XisZyeYxNBPOd6uAl0zOMHhFHYx+lRT+9hbP+pWjuSLcMpMl/ctB1Zptq+aBQ +86hZbaPdOE9wK7v/ki5xq+/pAO0N0bRv8I6yCftNYQ3ZENVUEc0DlIT9qGjkRW4e +ah4vhaFt9bbA8e73Nun+wvetzBNGW4hC8C0ftQ5+tSvkjau5hzBqPRL0rfMcrMwa +SCkqlnuAAAtuWYe/o8pwmRsc/XI9stOUSs9Vdb4fQOxVNUgtVfAA2jywYLoRMmZU +C74GpF63yVm7TfSSBiZIbsIS1HzwILii4bxqthkON0dVyfJJDZZ1ooRkvzT8vrJB +5PWI6+G3JqXlQcIgDPbiqKXndlSl+0uABX0YhXq6vLetwC9ghcwVEhwvCp7zfEDP +9D4j0pXK0AZYUvCE2A896/8SaJR5j75AKV+YyJBsBS+ZjCpjeB8jsSnF50nJspIP +UwvVcSgXwhm/YL98h6irwfQKwbjSaO7BzqcTExdtJF2iN6bXfUiLK3QtQC7KGdW2 +PmxCcfrPhYf53oBzi4n0cPDY1/9AQZzHFW2bbky1UgKZeTJzyiagrDFvxLD12rvC +H+CfRLol958CAwEAATANBgkqhkiG9w0BAQQFAAOBgQAIddy5P6q2foF6OdHu7US2 +zhs3xEwZ0Gbm67VPKu+VWGQhVQESMKyKldEG3ilGpPF9f7Ae0k779vqadL6FYtsL +gpBYYsVf8YACn8X782uwtDsEseVTwtAAoRqdZWBvc5hn4JzIEpR5Wb9De/V3yI/f +sc0RHAEZmcIiQvdBrrS4Gg== -----END CERTIFICATE----- diff --git a/mysql-test/std_data/server8k-key.pem b/mysql-test/std_data/server8k-key.pem index 493ad2350c8..faf4b43fa56 100644 --- a/mysql-test/std_data/server8k-key.pem +++ b/mysql-test/std_data/server8k-key.pem @@ -1,99 +1,99 @@ -----BEGIN RSA PRIVATE KEY----- -MIISKAIBAAKCBAEAwI8iAyRZZ0YU1o9gCVgGB0XxeHFV8eq5MIrNwzy5v2VuGO2g -uMkZVm/EkBnIZQnb/7+CoQitAU9ao9Q9eH5LSgGkfeh7BT592LlVWGDWHM7oMmIs -GWDz7QWZbcl3By4RbQuax2g4Ruj6MYDf6Hnw8f2plMP6DfV4rEl+1Rf94e5E88cO -MDJdqRkl5LshHf48hEhA9Vj0vxOMhWi77PXdxjjRsHcfpo5PjeJvSXT1P5Bljpke -WZwctSYkxLHeHvuWZcQxFBpTuF5iiscE97Q2pK8HyCcG7d3m9Ixi8WVA0J+fqRTI -jot01mda0MlNNaHVezk6Qp/k0PTGDy5CMEtWsj1tji1YxWmZNUmVlZm2hykrMtFQ -CM0lFEhtEJmFYTxBJiFVzB/PrbAvuYnYTqAY/3Udtpd8xfqL3JMXhgpk1Ak11YM0 -bVxtxozNuezCk8bBt8wEbyLgB7/g2Zsv1aBQzPnwlYOP9DCDcpTXtUvazJ9UO414 -dwskbA/ClmGWL7hftXqreluXeqmtQIvy1saNgdmUYY+dA8W5EANog78EgcysvTSJ -6NSNQyDitqQRPRUqggzWOmqMYtSTvMOAvxu0Kwp6NPDNHoI/JQ/RBKgKBRmw1haD -Oa8LRX3LFH5NqqrCOahGOKu9qyq9NEN/2iXeK/tpO/47h/2YlHZKvwSjMeM6/28E -+vok5CqJ6Q6/RExyhYI8iUoDYwFBklPQgmBu2P+MorQaOyBtrnSSME5I41Gmy3OX -BhMDMiObfaLHOqmvl4xR7f76tLQao4f8z4yO5oAVA/3+fb2xdvFfswkrTE2nfLVy -sdbbOMBnpFS8hwmlOboafj90YK09S76UU/NkFsczNexBAJW23plionoomkVN+s2m -d/beWHJQyH1pONsHBITYTTn3UBNDri2vRaQqOVY8uLfYJqQ2ySOqqrhJCyG6nnor -f00pnw4AHrRepvpJ/o3ldFfYutmSLNKshB3ypqREHL+IQTJ+0cMvbrwPXRmmj3Qr -Z7rdqdtotc6dJUjfVAjQHU8uWyS8BQ/7WEb6AspTkynPECfCoBjQ9dS5PF7fjmz1 -fLm0VMw5Fl082pazw2zUcF3TMKemvW/dQbyo3kJgWZqFJQ0qRcMFtG56Sk3KjArl -bDS8IJttSsrKtqY6oNvDDiAaEht33csdf8MNDefB/ZbSx2iAmaDZijMho4uiWqd+ -JwYCf+1gETc0VBd/TZAUHmk3DbrwK/CjLWJ5yHao6sjnOx/GT8IM16zwd1Nd8FC0 -35sDyk1B4RiyJTCGHWPlZ7FTzWtOgxq5Xi0FFWvUjrGX/DEDV8u/J3/NXyd+Zuc8 -Fwm2ESpPM83rGtNv1RWLi85oa36aleV0fxdX2QIDAQABAoIEAGv5ltvmLQ/A93xc -x0BWEINRkBa2jrfpo9B5dOnuikWtza/Cx+X2NfQHFlSrcHhfr/JX5BsCb2iVo8DM -CXAgeX1VMHS9wQXuxciaHCZDnqxmxUNDU3EjsYQOKLusRcdL6M+Zuz/ny+7PQ0Qw -/N0yS46Wa9oUjon3RKRvTeSV4HIpFpcP3n/eLjDc/ielWuujnTGcBnjNWegvQROp -5/7221YElGh8U84kbK2l9DtfjwoGoTv11lPvOxXE/scg6em7r9j+y3p3TMzMeDtT -YBC6CA4Oa7GrWLJXROOKOQ0ddtvFNlUsZ02vG2QCbqU2y8mwJrJDI80qNbeKGel3 -SfwkssedtGoOOYHxNczwpyVNHVHrHuMPBe75gbo+5pFxVJ5ymCGWfbLJf73oVsqW -ZimoknvkozW4+mlVlcmo3X73IxTW2U4RlXthYdj9KXsBLRaKVCQJDc934eHWkXHU -GF2U2NonqOVd8YG/FmZQ2ig6EcW97hC6wnsWT2Uc7UNAE2RM4bY0xCUHaQiKTrEs -CI6wpbbTV+XhDu2HmL9G+fsuSIu0RoSOCmr5jQDAVwCNPXFgBgcIxbPZ/UCJ7RHj -GrWPBldAN8ip4osiA+B3XwBabcvwXP2fgBP/eLWN1St3q3tw5xpHpqCuhNuPSqsc -0ntz0oIdJyRR6fXWmRFex4kXQ597z5ozm0uyg8arV3HJFxDC3DI6kKfs86/oqMSW -l+9g+d4x6VrUOCTDk0bjN3T8HQ9ASfy9JVacqk6yuXX7a0WeeT+x9JsvFAjg2KmG -CJUtm5w5siItMDSPpcRE4hlfgh+M7ZKS3PFgH3vvwfPMbC/IC93QoSaFzRJMyobX -ei6PNwqJvL+HADlMfLmehE2w9ycp4Fe1Gw/NW0Ed1S6Ajo45hgXQJSIrzla6eglg -JPsPpQ8b+weZNQ8zvc0KvfRJmZKKEb9dHvFdi68I1kV8aapQsjrMOjwHC2pnCFh/ -axkVc7a59fKUs7L6nAJhCs2sSixTorZz5PvJ6mXhWu72TCzu+kThNnEORrlWPHQl -RFEAFpDDaGSzOMlhb92CWUMPyZU2qtzMzv4QGbP5YqTy121hXuT5OBKCF3eNLihV -aje16k0RMFqqW3Olbm7Mp2P1C6DuwzsUJBnNwB5JzhC79Po88zNAl2d1h+qysKU1 -jxF316nhpWJ2dGJ/sbJ+XpUMd/tVrNFQMA254GFfXycsfBoQOSY5d6GfRwKUDOou -xImbIzGUAaIYdsGKDuKtqs5S21JMJjJ/J5CwjLu9tbpP/jsp22KHCpraHAQCupSp -+SFwWI7tRUXzREuxJixfUOnJFQYOATnMFvvtk1d6v4xoPYCVEhHq8gHqJkTyTi3Y -BPVwT1UCggIBAOEy5gThTrEqSVFUcFJm9bJxtWZt/YhOIJWNNxeaxExHzy5hPpsw -fZXtN4MUCeMSWI4isgIujmltwgOHMjQqsJPISn/1gVrqLmrZ2PnFzko/WA8rMUfd -EUnOOpj2bKpChlRGHi76ZV4XGgoTXyO6mrVUcUgf3reSImdcdQ5IHa7J+lWhCQGb -neZIyDOk41LX1TxjcYkY7vuUgmbBYComXPm2UaY3HN4E/3ElXntj6PrlozL33A56 -z4UPfv2Vv9kl0ydkTJe/WcUN2htqLFCYygF2XLlwbv2SYDCT31PkJUORbScUM46A -DOhlxvLBFcpF+l0RtCtvnrKyFy9yZJKrcLh9x6xVChZ/aQqSptSHjll5IEcVm54Y -Z1TjWizCI4txnaBFV0UCLt1CZrllXnyIksZLS4/dVqUIKmkxPBQUpiD5dmgDcmPB -/LdWzS6k4MH3J3Y3tu3MNPHDwgUtnifSZrsWSYPK0F8J0dMU/mLaS9eOplAH7Eo1 -t7OrrImvitM6tUdErRYilIaoS/6YPmsPST5gY1N4n8Lf4sAE/tY8fwaWRpTVSrIw -CoFwLtHESUOhqfuAOdr1EkDfo/RQTUVdnmWZ+D0j3du8MmsMje4x3f2CjBDXqArl -gNnBQELDmrdif8KELNjlEpTIz0T7wEfquhVQ2dzhFpL7RLAgggD+oEBLAoICAQDa -5WOWrAtaI1cC5C7LFxM2qXTHGRttfAtVxuigJapLqNASJuu59GGRxsCVwhthbNFh -aCMSj+fZK7QNFkaoPwuZCEtzy0ErkVZzxYp3cP6b99mzGoCcuqiHiW5qhEkbxwdC -f3YEsSGqE6j8TPW8feiziqo8q+QPSudI9ngkH1gjgbIrTu9iaxKJcF2CwBxe5tfB -uFBNPIgJAaLPejRKQu17MAV2jDnBDIsZUZnm53IxQ+giIYUBay3cfC1KMJu/AnZ/ -CxETjgqqnzqdFW0b0o49Q6YQa6QXAiSjs+lL/BhjbdA5quVdFmA3CoASFQbihYfM -4vilUg7Y4wXfzS7DyBZdfppIn+HI8PPSMv/lfdsQXecl5TU1fBDPRWYPpTZqm1II -HDCkmGRKet/j4/oobabNRrJ6PJcxNjqeMVv/a72pypDRPIXzNxLb1BkfWDGfgu2R -YAdRNBSJSpdoHDZ+1VO2A+/8gz9Zuiv1WxoX7+u3pCAd+0vCfHiaXiFVc7fI8F+m -rtDmN5p3DD9l1+/v7yd+7eUezwxYecElw5E5MyAJRTYGrim8g7XvF/u9rXvH09VP -TeIE8oJ7XzrxCmtGIxlJs6FmgUbUblOyfPZDUqPnzlo8Ru1H2iKRo2FPiMfij8mh -H3wgFTnZpGDQjw/xop51bxVueXrmOeguS0wmk/8Z6wKCAgEA0y+bPApadJRWS1nn -N69sTBqMZfFR6Eh0ECts9criuTJCXZk+T+SqcTYTb+4T04k52Jk63Aby8HXIkuxv -LTK3gu86xkLiOvMP8o43Bwz0BvbeSuNThLQQ6Wjn1NiLUSOvu0pCNgYFl7YMalR+ -TRBK0y/MSDny762wa8Pt1iXVCDxLcY/h1UstSW8JqDzCHcdgJhCPwWTLgMxleZ1w -5DYzzM2oRjq67I49Sssjjo1ESD2fzUVZbY7IG11L1t1fG3F4UiGiHlCJC92Qo1Lv -Geoezj5EeHay70Mcx5F0xsRWGcZAWXx9WO5GrI39g1uFZro3Lp5SmsVDSwrt6UXa -gR0bSThTTw40tqJnTE34+6ff25JWrbLay+jQxm+q+fxZvwQeMNW2IHYKot4JXWVt -tVWSZzjnNJP6FCvTMfDFCYPPw26OFr7cwCaEKx7QriRazitMK3XWK6zsHalZwudj -wK50PpCJAnno7KdVySCP6v4ST6Rr3POBKJq1ml2tITWo96u/ooUJ2I83QAyFr8zw -BBBCvKdBnl6pW+P/TdmhbiEvcmrs59gaA34/6+DbV0Y++piZwswd9XML2iCgLZY8 -0IcZ6uf4PsXq4Yzcrz0HwM+tAXcyiPzkjstpCUxMShALgFxzuWOgdwpjYXnrviJk -0EyUkzbOCHBhbhcK9CyYHfyrJX8CggIAdWwgJC9eV5glkPN+9osGT4hPkI4zXGPy -YK03FNGfrL59/37JbRNfU6fen3dk4LpTB4Gpbserg6AiEfMlLBPF0O3WK+OYrhpk -2e3Z/YCr1Fb8fUt2Op0W0r4ycQlNfo0ho9ZkJNgwSuAJAm72U4rnTYjREYLT8DAq -KcWtZRM7YLCuNvU9DPqLExcn0n/juDT1AIIy8XvLLamnAM15R2znn/F+vL00Lg7g -f1B60pbNdwgKemSoyL4J+ADU+rtgkPJtRnFVU7walLSd6K4ZvZcRnmOvrZdQitcn -eHmGaLBvFMdPr9+w8mKScnQ7h3eoHdOrqYkIAQcn18jQ2eFjeLrY5IaJlPPPVs+K -u/OHuj/tR7ZXzMhL5skK62U6/qGNs1pmgts8bM8i3aFUgRdGlnFbzTpje5cNM+T3 -RO0NgNL3ByIW1Wc2I+YjQ7FfWKUi2YKOljGBO1pIue09kyevRBKDuVwbXMW7MhLg -idm5AaY+OGDeqbaoSUgkGgrsrr5IlI39gZi9jwG85qe3Spavq3ILKdfL1N8UrFGD -/xIN0TVPtilede7vjKTK79tZu8JYaDWGc+g/mo/M1wmawLrqGNGzOwoVRruKl2In -m9PU9wBZ1HuphDQ4DRdC/AU8qkGhmDOx4bDWEQ/R3KKFHNvhnamyfyR7xqt79gyS -NGNIElnJuskCggIARFaK6yAVmaL74Qu3iiELj8FU9Cw8kPP5HeWUfGxCjlegdH3R -FBtoQlDcQjYzO2uZR94Itg3yk3Dt+xbf7KxUsODwlgLj1UhV4eOXUDTosBFTrbTG -v9gnRVH0Eyu9tF+CMUcCXhq6tnIrQOVv1ozcdXfIpk9gvIbfh4rlo6X0iM8Xge2t -Vo7awq05t4wJBkO1xUtOaw9HabaszK/CU1iNV7cIBmaFF3AEP/KVfOs+kjubc9AF -mqC+LVVClvJPNzm1YA5JZlxmQ0u1xXFqZv0OMoibgY+gSzaiAQz3eKB6vEv4Xv4U -kaF9nEUTEjowpTE6uX9X0mGkXXT2wXmlTjosZFnxRX5IIrRNug30plRra5CNYPGp -3uTmD/D7Nzi1iYitJg3yhrTQmCWiJY3x4Z0xophLkio2nlJ9WoTKf1AwTIATY7fa -pX9bxEKldYXrYZNFlbqBPFgA/36v+JDVfMf2E9yRMCt0LAJ0HUM6zP0ngMv+S1TP -Pu6X0WXR9JeuoaF4uJSty/xwdpST/CkHflFLVsk5n3tNQfWGjqoTSOJMgL9NRY9e -Pc/OshHZHeCVFUSXtcf1pfmmBtT6FHX0L4cgVqA5xO8RYapnLDAFLXq2/dRv3NwW -W9CzZcZKh7jmJw4iSIY5IU1+ThgugWoxlkcmjs/egjBclL8BBfqRIwx/vOE= +MIISKgIBAAKCBAEAyqodxBHskfDH/1+QkvxADF63PQDFINUPiTEH10FMi2CAqjgU +3pNrnHSIQWi1AkEBLYaiepVTXntnL2weKVH5RP1KgL6yI6E+GzjPiMRx7vhrQcUt +wMNSrFl9gTQZlTK4mlG2QTbUxKGuhOY4uei/lr4Zemt3TeDe5rO2a7w93Wi8S8Tr +9TaT7VaiFVCKEOjWIu1ssc3DGMn2CuHeYWVi1hRBjLX7FGjBzxJdQSGdVxFDfbtD +LCG7w0R9qM8fw3F1tUfCfc44PHNknhXYpyfPvUDIRQjjyDmoC47CW3vxR5ESkczh +AOCUW70y5AyNw77MdjJSEmmwGOCwwnY0Wl952faBnQIKYWkcM85J+nYDHgdbJwu/ +NJ40lrgDm1A6ai8XehTPZWMAN1Koc85LFED00ppWVDO4dy5CW4/sHxj0rauKSo1t +cCXzWOfLZlEUfRb0621WdnZRbtYd2tONwGRaZ06v4r8z0bj2KvxXh6c1XoDJrPyH +yXEXkb+3TaPtPBsn9Gag+UYDJ8zqgPZLQPZBlM29CrPvJr7eb2muDz8cVWMzkJvt +yloSTd5LBsKikrBCPTGvpBUSFfiK6YiNz/2FZlBvEfGfSPO1up2GaCSiXah8VEL6 +2LXF8t0OD9Bo5FR+xbmgm2Utd/SPuTAK1YZc7cl80dqdDWNQ7uUekmPMogzoSpYC +TdyP33yPCBioMIjXr4mt/FdLEPnxy0jotjvIP/zC09FKEDwba2Tc5WUeW7LaseIk +l4/uwEuOGIN8F6Y8RbNgBiPyLxgTnheKxnJ5jE0E853q4CXTM4weEUdjH6VFP72F +s/6laO5ItwykyX9y0HVmm2r5oFDzqFlto904T3Aru/+SLnGr7+kA7Q3RtG/wjrIJ ++01hDdkQ1VQRzQOUhP2oaORFbh5qHi+FoW31tsDx7vc26f7C963ME0ZbiELwLR+1 +Dn61K+SNq7mHMGo9EvSt8xyszBpIKSqWe4AAC25Zh7+jynCZGxz9cj2y05RKz1V1 +vh9A7FU1SC1V8ADaPLBguhEyZlQLvgakXrfJWbtN9JIGJkhuwhLUfPAguKLhvGq2 +GQ43R1XJ8kkNlnWihGS/NPy+skHk9Yjr4bcmpeVBwiAM9uKoped2VKX7S4AFfRiF +erq8t63AL2CFzBUSHC8KnvN8QM/0PiPSlcrQBlhS8ITYDz3r/xJolHmPvkApX5jI +kGwFL5mMKmN4HyOxKcXnScmykg9TC9VxKBfCGb9gv3yHqKvB9ArBuNJo7sHOpxMT +F20kXaI3ptd9SIsrdC1ALsoZ1bY+bEJx+s+Fh/negHOLifRw8NjX/0BBnMcVbZtu +TLVSApl5MnPKJqCsMW/EsPXau8If4J9EuiX3nwIDAQABAoIEAElnTjqq502AsV+c +hGfId4ZDdAjjU4LtyJ+/I4DihM/ilxeQEnb/XDWhu4w9WXpEgyGzJvxRQ43wElKJ +zW7X4voK58Yzy5++EhmX/QsjY8TTMz3yJf0wgawtCZkXfsCcS2KRf/qk2nGRwf0e +yaMEWwhFOEMv01lgvjs/Ei55Usrz2Wd0HqaFKxUGkNQ5hJhVTOH/rqPDzAsZc0VD +w+Dw8NhrI8bMTvF4c+IFW8NwYmWbuh87CTxdx30VPJI82ttWJ/UN1bLtU08J2IKt +lPgOIl8ArMjcTGxD/cqZ3Wl3Pc/XCqvGUiSYMwP7Rgh1R4+DdtjEpxdGMmMAVuVI +HPQyqpa4gv+UMqBPish0yjSuM7jXnztINOvg9Vk1sxC5AT9eaRltmiS1s+lVxe+T +43ulf0ccYXJD/WclWSGCwloNFuokPIV+Lgo1pKsp4XDgoxQfkXwH8Q4dEqebY9rT +Tv9FGb1bMbdl22X1oSu2lBltBZaB/QnruV7L2GaQ0tqLKizgBRuvZFSE+DWdMb6d +9mnEB8LWtca/nzogXb5qv4GEMUX4FUAmSf1FnGWZwwDi1DFfJ860RVKf0xokGGQ3 +cm3H/F4veds88Z1hsAu0bG8h/bEAim+Whvag995cFHDD4on41KXW8wX1on9VFA1W +CkaGUPhLRytXDBVCSJkOYYFSJlb2wqONiWe4Tn5hsantCfliTj/GVkgDq2h7dAGR +WyoqTntJAv/xJsUOV9WmGXnWNeZX8BSO3P5dnXnMzhCWQGoprXmWFyJ3TYCJ2+CO +rzkZbtuKvTvGc3sDJgrSVmmg0BrOkH+GyYVlJdTDBmfzoORludDCFHECa8oK7NwY +t3o0eNlG6IqTxl2HIoPneW9nXFQtCXv6tpJjljwjlz5WpJG+kBW6bDedcxZu7olZ +fqtnyZTB2SjzzbGdQ4JvFup8MxNyPvYiqumQXJgkyXFVDl/UFhjWuGe04i8NBJgJ +xORcjfgLrKH1XKVBWPJdh/2YeUKIIvQ9RB4WVqXgGmD/21tgv1bVEMYabh23e/HE +Fe1U2XQPJKxGCEtG6b4zhFP+PeZACS+Vk5IVJYK9n4SepPBPgX/wbJLOcKGpsKjp +yx5WjopMO6T+VUV8HIduuZ+E8+uAILHDmo2Bq+LHblaxd4SkM0+hL2H36imK5CUO +5fLuvHW88LvFtQw6xhP20s+BnmgzE5ZvNG4Iedkjvwe9HmdNDew0UYT5vNJN0ehh +OlraBC++JYwEclrBD9SRvprT63XKDG735pPvzLQi7WKDCBn1/JEgxDIO8nkMewOZ +FU48Mdmkn9wqPeIigQciwl62fuAQCGRG+RXMQqra4A1apqMZQEauTK50VhHDGdbc +ye9LHaECggIBAO9lAzoYS/Lu0ticMt24P8BSbGdxSNIpEyIlTTs+7A0UjpfXsoK9 +4EJWZ7lhgbQh+SCTS662SeC+s8M6bT+3mELxUC5S/N3aCPyfjcM3JaoACkI9+VMn +9otJZjAEwH7cNpMN0Xa8fHCEma3l3XKiVxEJbuJC86S5mpkjeXVnDajAidBtevBd +LWJ9n2yXk+ZKUyI0mjpqItwUxOgQ/MOIvqAu66xyjg08/I1QQTuIrReAA+oaVKhp +c42Ufn26hUhNrQCBAtMAO3VC/chciet6vEMNEM13GqLp4+PcPhRX90gO4+bNrScD +WgiW/jc24CGan8gAenBWC/3l/C6JUsMp+ZYmPozsa0zo6edgiO/f2KXe5nP87wZT +MxaYJgnyXJxMefI79kUHPrhpXZxuiSCEWLhCBN34Lhpr2L491i2g/FJj9i6N3EzE +N3ic5Q63o4QFusjqIm3taQQFoGP2Cgg9owz5WJ0uRz/gtOE3XQiQA7+ozoAXOlTw +pJK5MMtVrEoOLIbVJIpxfDcKDp3yorR8QCQLHgDBmFeNCDmk+7YP33dRIc/AVNLF +q7cecqEc7D8AkXX8Q53GfCEg+uqbdeMQXK4BUE9iwRK9RiFhas/RJe73+Iio3S0L +ekLpnnOfvk744ws+JWsLpsfC/ZE7OxBLPtq2xvGl/RT2G7tCjmpX3CbPAoICAQDY +uOEJks2T105EcMPJjzNHCCqjK6S7qZaWkF3KT1Z0Mu5oUZwwHamsMg4BQJ2mjMrL +fRBKfXQLA6vgE7zysw3F300RDxE1RVow5+JLDQ4bqupp27/M0a8fuwksyOdKHqCV +YHzuTCxbVIFZawTjfOxJVXDHKCFCilfY1LsA+V+oFe3Ej8YYxWXkXA9ZLigpmt3s +Wu6eFcZgF3utzIGjI6eP6lL5bWp6Bh9Avp2xrOvpFwE2m02Y7/Zom6MT4DXvByY2 +KHHQLsasEMpeLuxQXjLeTocwcxBwBFKhX95yFuv31k00VydT+NExtaZeUYi9l19J +WmM4GjFjAqa3uUwMNVv5JfWtKMyk4FOox2XftLvMiIhV95B8hAGxtYr3hPkGg80O +AWPq6OKUD332COXRaHkmL5aQdN3gP5zh9+rH6icLrrZbrQidVRyDw03doRoGrH7i +ixXLyYoW80PHgqUDPohd5bFkZpi2vwXMl1YQ2TfN9TvYFSGme9YCm9ZuypnqauW/ +aAf0FI1MNwS+XDREtzPdFi0me6WxpKL4a2Z3GGNxIFuBjQ/uydWpjxkny9qI3KAp +SgjI3kBUDGq3gf0R+Xo/d4d/4asK9Nv2Fi0X+RfGqioFaTbQl/1zhNdvhP9IcwEJ +DLVQ3UhMdfg285RarC2Sihui0M8Smi9od9Dj6rdWMQKCAgEAiQVRFoRnnDGz/wVQ +W/Wkj6jdoUuG+btG10lwbhOyuj3k6+Yqp4iUfoPENKgpu/eiB1InhGWT3Y5ph7m+ +ZDTqco56bTlUwIqWkDmmw3CiHy6MsKOWPFFoXQry8VMW9sWGex7yoDp8I07SQ2WJ +HZ7rpLW4gMr/d25AnZxfXaJRgCBMAT9YmZFLc88hW99aaPproO1oxTyQnVVJ6uYm +NqjjKv4QKJEc21jn2N5xp+iv4f6Evw65G/fXitbOm5oRxXOoLNyqyCie35wrc+37 +hwumC97DmkasuUiUBoy9/5jl0ZmsOiPJEsZpVvdNpD7FhJZjE++qJPgrPvTPJbe1 +5jz1PUrAjJqZQ9kgYC2x01JVR4NQdlz0VrNyT2FgjFrrRQ7E0bAeYh4meRjd2rat +yC3YNgabkI0HnlnSIfl0yIMXSPUsKDNMP6gjc+aheI4FioBZC7xvXmn/rKynw+9E +iLj2xWtGnBir8VTlUu8EUe1UJ/Qv1cL1wT5HhC95TTjJN03rkHUYyCDyjvIzsZX6 +KMHhWIAAeUBVuO7hIVVcOTXWmw2WA7o7ErTPdy13QN40Hk9t8pEkBn9f9vpQg83d +aMypr3LTC80jY11wcZS3tSEpzCCkYVv91FV4cioTZmytWbg9A+dbNWzi1f22ctTr +FoVrAXaSYie2trOy5bjPmPCW8qMCggIBALQUKymBSkDmTqqf6I+65ajIKGWdBizJ +Jc/F9aj9c6DqER+tcFKq0ym6DdkMj/KsWnXrXXYH+DyOuGpg/EfOcEtS2P6rvmi9 +T8wDYg1qs6ZZxp5fcmgGc7Wx/FWyOj1kZZq5qhV4RgM9nJ1oR4+fZdcpn6RcvAZG +XehWG20byVgpoIAL11cN7zRpKne32rd3b5/NjyjcfxGpcaNgovej0L/MvVV0jV0H +aUCrIu1X+k6cRu3Q7hF+kwkpCcCiNS6AikfGI4wQ0hR3fy/zXXkKTMpcBglEEwyB +Cwf8WSID2d79uvka0hr8TRc5ERyeMzkWZp7U9EzRtufGdDGFTqN2Uw4bdKCFnkYC +AIHl7ciMrN+vM1n7c5uDNMUtTGOPojy/l8tjbFrtWBgfJ1Mg4ZW3cbNBJ6Kw+Qw0 +z28USYoEDp2uduiGRvo0lpUF29Wk37Nb8bLcTygeNxgK2u8Up3iipT0gdt4uQgbX +g0IVHfayB6SjeS57oJJto85XHz7AKlSWroD1OGagDSifLtneU7AlanryymGHrI6H +dsNkuqeLJFYDxQVI6UxJebiCpyxiPxwp9wtX8SS3SEyOZL5GzLn6ypGiCH1CTpW0 +EHHSy3V4DUGOc4w7eMirAnbSkxCfOmBA70NNw/uFY2XlQHKow0T0fImfKIeJagbT +B0GPDYvUpLKBAoICAQCzYnq8xupXK7lvTLaj936qGSe54OC2sj9+UpsFiPxglNY2 +sO5zKWKyY7+rjK6zG2ciGfPEDsZNIqKw1W/KBfR2kRLqkt4bC3fSCvUztx0vtGUe +veXlqiwETdE7RJXoaGJrgJArYJvpOd8PtWGeM+sSJNNrUlGlJnSiZ0CcypqUZgZL +WzGFfLOQYAXCykdB1iZkBqU2C5wktvCb9sVz6G3TmAwSKTENOWWZWmh+W0J4pZFV +ZEyvsxViJRQbwxa0kC0F5J/UtWZknO79/ZFj1H4jiAR45EjWHE+UZAkFwG8BSl54 +EKOx7GDanuRILr0dtbyi4d31nCYXdjs3x2+1N3exw4oKQIvNuF54WoowbNPu0kEb +G+7/kLwcJqRnSV4AiLuMz5aOte7JJSw5tzgZZlAQwJO7IDfrLqodivcXF5yirwiF +dyBpzSDmupy/aTHnCpT+l0H96jRU2awxaeRHZUqZog8gMHsslNVZEFvUFDJ7AUN/ +yyfUzJYjH18pZt0hS7jNb1O7KxZCkWGMiEcxHkgF/UINab5qruNBVKOkJ5vqGhYi +uNkgeGsQtXJcpqMRRiVXJE0kE+26gk+iaYnBJN9jnwy8OEAlYFUHsbCPObe/vPMQ +3RLl+ZoKdFkN/gTiy70wUTRVw+tWk+iAZc7GPX1CqDFOqGZ2t+xdF8hpsMtEww== -----END RSA PRIVATE KEY----- diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test index ad051503fd6..19b8aa236b9 100644 --- a/mysql-test/t/openssl_1.test +++ b/mysql-test/t/openssl_1.test @@ -15,8 +15,8 @@ insert into t1 values (5); grant select on test.* to ssl_user1@localhost require SSL; grant select on test.* to ssl_user2@localhost require cipher "DHE-RSA-AES256-SHA"; -grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com"; -grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB/emailAddress=abstract.mysql.developer@mysql.com" ISSUER "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB"; +grant select on test.* to ssl_user3@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB"; +grant select on test.* to ssl_user4@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "/C=SE/ST=Uppsala/O=MySQL AB" ISSUER "/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB"; grant select on test.* to ssl_user5@localhost require cipher "DHE-RSA-AES256-SHA" AND SUBJECT "xxx"; flush privileges; From d9e9a73e8f1355a24b27d64d56d555d045ee0b4c Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 30 Jan 2010 20:49:25 +0800 Subject: [PATCH 149/157] Bug #48321 CURRENT_USER() incorrectly replicated for DROP/RENAME USER; REVOKE/GRANT; ALTER EVENT. The following statements support the CURRENT_USER() where a user is needed. DROP USER RENAME USER CURRENT_USER() ... GRANT ... TO CURRENT_USER() REVOKE ... FROM CURRENT_USER() ALTER DEFINER = CURRENT_USER() EVENT but, When these statements are binlogged, CURRENT_USER() just is binlogged as 'CURRENT_USER()', it is not expanded to the real user name. When slave executes the log event, 'CURRENT_USER()' is expand to the user of slave SQL thread, but SQL thread's user name always NULL. This breaks the replication. After this patch, All above statements are rewritten when they are binlogged. The CURRENT_USER() is expanded to the real user's name and host. --- .../extra/rpl_tests/rpl_current_user.test | 127 ++ .../suite/rpl/r/rpl_binlog_grant.result | 42 +- mysql-test/suite/rpl/r/rpl_events.result | 42 + .../suite/rpl/r/rpl_innodb_mixed_dml.result | 4 +- mysql-test/suite/rpl/r/rpl_sp.result | 16 +- mysql-test/suite/rpl/r/rpl_user.result | 1755 ++++++++++++++++- mysql-test/suite/rpl/t/rpl_binlog_grant.test | 8 +- mysql-test/suite/rpl/t/rpl_events.test | 82 + mysql-test/suite/rpl/t/rpl_user.test | 83 +- sql/events.cc | 79 +- sql/sql_acl.cc | 124 +- sql/sql_lex.h | 25 + sql/sql_yacc.yy | 36 +- 13 files changed, 2319 insertions(+), 104 deletions(-) create mode 100644 mysql-test/extra/rpl_tests/rpl_current_user.test diff --git a/mysql-test/extra/rpl_tests/rpl_current_user.test b/mysql-test/extra/rpl_tests/rpl_current_user.test new file mode 100644 index 00000000000..7ec38e0c151 --- /dev/null +++ b/mysql-test/extra/rpl_tests/rpl_current_user.test @@ -0,0 +1,127 @@ +--let $count=1 +connection master; + +if (`SELECT '$diff_table' = ''`) +{ + let $diff_table= mysql.user; +} + +--echo +--echo +--echo +--echo TEST STATEMENT: '$statement' +--echo -------------------------------------------------------------------------- + +if (`SELECT '$diff_columns' = ''`) +{ + eval CREATE VIEW test.bug48321_v1 AS SELECT user FROM $diff_table + WHERE user LIKE 'bug48321%'; +} + +if (`SELECT '$diff_columns' <> ''`) +{ + eval CREATE VIEW test.bug48321_v1 AS SELECT user, $diff_columns + FROM $diff_table WHERE user LIKE 'bug48321%'; +} + +while (`SELECT $count < 6`) +{ + --echo + --echo TEST STATEMENT: '$statement' + --echo CASE $count: + --echo ------- + + let $user2= 'bug48321_2'@'localhost'; + let $user3= 'bug48321_3'@'localhost'; + + let $user1= CURRENT_USER(); + if (`SELECT '$action'='RENAME'`) + { + let $user1= $user1 TO 'bug48321_4'@'localhost'; + let $user2= $user2 TO 'bug48321_5'@'localhost'; + let $user3= $user3 TO 'bug48321_6'@'localhost'; + } + + if (`SELECT '$action'='GRANT'`) + { + let $user1= $user1 IDENTIFIED BY 'user1'; + let $user3= $user3 IDENTIFIED BY ''; + } + + if (`SELECT $count=1`) + { + --echo # Only CURRENT_USER() in the user list of the test statement. + let $users_list= $user1; + } + + if (`SELECT $count=2`) + { + --echo # Two users are in the test statement, CURRENT_USER is the first one. + let $users_list= $user1, $user2; + } + + if (`SELECT $count=3`) + { + --echo # Two users are in the test statement, CURRENT_USER is the last one. + let $users_list= $user2, $user1; + } + + if (`SELECT $count=4`) + { + --echo # Three users are in the test statement, CURRENT_USER is the second one. + let $users_list= $user2, $user1, $user3; + } + + if (`SELECT $count=5`) + { + --echo # CURRENT_USER is not in the test statement. + let $users_list= $user2, $user3; + } + + --echo users_list= $users_list + --echo + --echo # Connect to master with user1, so user1 always is the current user, + --echo # when test statement is runing. + eval GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; + eval CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + + if (`SELECT '$action'='REVOKE'`) + { + --echo + --echo # Grant some privileges to users at first when testing + --echo # 'REVOKE ...' statement. + eval GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', + 'bug48321_3'@'localhost' WITH GRANT OPTION; + eval GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', + 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + } + + connect (conn1, 127.0.0.1, 'bug48321_1'@'localhost',,); + connection conn1; + --echo + let $temp= `SELECT "$statement"`; + eval $temp; + --echo + + disconnect conn1; + + connection master; + sync_slave_with_master; + + connection master; + let $diff_table_1= master:test.bug48321_v1; + let $diff_table_2= slave:test.bug48321_v1; + source include/diff_tables.inc; + --echo + + --echo # Delete all bug48321% users + connection master; + DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; + DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; + FLUSH PRIVILEGES; + + inc $count; +} +DROP VIEW test.bug48321_v1; diff --git a/mysql-test/suite/rpl/r/rpl_binlog_grant.result b/mysql-test/suite/rpl/r/rpl_binlog_grant.result index 4a789f361c6..adf2175f3bb 100644 --- a/mysql-test/suite/rpl/r/rpl_binlog_grant.result +++ b/mysql-test/suite/rpl/r/rpl_binlog_grant.result @@ -17,16 +17,15 @@ show grants for x@y; Grants for x@y GRANT USAGE ON *.* TO 'x'@'y' GRANT SELECT ON `d1`.`t` TO 'x'@'y' -show binlog events; +show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 106 Server ver: VERSION, Binlog ver: 4 -master-bin.000001 106 Query 1 193 drop database if exists d1 -master-bin.000001 193 Query 1 272 create database d1 -master-bin.000001 272 Query 1 370 use `d1`; create table t (s1 int) engine=innodb -master-bin.000001 370 Query 1 436 BEGIN -master-bin.000001 436 Query 1 521 use `d1`; insert into t values (1) -master-bin.000001 521 Xid 1 548 COMMIT /* XID */ -master-bin.000001 548 Query 1 633 use `d1`; grant select on t to x@y +master-bin.000001 # Query # # drop database if exists d1 +master-bin.000001 # Query # # create database d1 +master-bin.000001 # Query # # use `d1`; create table t (s1 int) engine=innodb +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `d1`; insert into t values (1) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `d1`; grant select on t to 'x'@'y' start transaction; insert into t values (2); revoke select on t from x@y; @@ -38,19 +37,18 @@ s1 show grants for x@y; Grants for x@y GRANT USAGE ON *.* TO 'x'@'y' -show binlog events; +show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info -master-bin.000001 4 Format_desc 1 106 Server ver: VERSION, Binlog ver: 4 -master-bin.000001 106 Query 1 193 drop database if exists d1 -master-bin.000001 193 Query 1 272 create database d1 -master-bin.000001 272 Query 1 370 use `d1`; create table t (s1 int) engine=innodb -master-bin.000001 370 Query 1 436 BEGIN -master-bin.000001 436 Query 1 521 use `d1`; insert into t values (1) -master-bin.000001 521 Xid 1 548 COMMIT /* XID */ -master-bin.000001 548 Query 1 633 use `d1`; grant select on t to x@y -master-bin.000001 633 Query 1 699 BEGIN -master-bin.000001 699 Query 1 784 use `d1`; insert into t values (2) -master-bin.000001 784 Xid 1 811 COMMIT /* XID */ -master-bin.000001 811 Query 1 899 use `d1`; revoke select on t from x@y +master-bin.000001 # Query # # drop database if exists d1 +master-bin.000001 # Query # # create database d1 +master-bin.000001 # Query # # use `d1`; create table t (s1 int) engine=innodb +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `d1`; insert into t values (1) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `d1`; grant select on t to 'x'@'y' +master-bin.000001 # Query # # BEGIN +master-bin.000001 # Query # # use `d1`; insert into t values (2) +master-bin.000001 # Xid # # COMMIT /* XID */ +master-bin.000001 # Query # # use `d1`; revoke select on t from 'x'@'y' drop user x@y; drop database d1; diff --git a/mysql-test/suite/rpl/r/rpl_events.result b/mysql-test/suite/rpl/r/rpl_events.result index b3fd85d7e28..206ec52718c 100644 --- a/mysql-test/suite/rpl/r/rpl_events.result +++ b/mysql-test/suite/rpl/r/rpl_events.result @@ -251,3 +251,45 @@ DROP EVENT event44331_1; DROP EVENT event44331_2; DROP EVENT event44331_3; DROP EVENT event44331_4; +DROP VIEW IF EXISTS events_view; +DROP EVENT IF EXISTS event48321_1; +DROP EVENT IF EXISTS event48321_2; +DROP EVENT IF EXISTS event48321_3; +DROP EVENT IF EXISTS event48321_4; +CREATE VIEW events_view AS +SELECT EVENT_SCHEMA, EVENT_NAME, DEFINER FROM INFORMATION_SCHEMA.EVENTS +WHERE EVENT_NAME LIKE 'event48321%'; +CREATE DEFINER=CURRENT_USER() /*!50000 EVENT event48321_1 */ +ON SCHEDULE AT CURRENT_TIMESTAMP +ON COMPLETION PRESERVE DISABLE +DO SELECT 48321 as BUG; +CREATE DEFINER=CURRENT_USER() EVENT event48321_2 +ON SCHEDULE AT CURRENT_TIMESTAMP +ON COMPLETION PRESERVE DISABLE +DO SELECT 48321 as BUG; +CREATE /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3 +ON SCHEDULE AT CURRENT_TIMESTAMP +ON COMPLETION PRESERVE DISABLE +DO SELECT 48321 as BUG; +Comparing tables master:test.events_view and slave:test.events_view +ALTER DEFINER=CURRENT_USER() EVENT event48321_1 RENAME TO event48321_4; +ALTER DEFINER=CURRENT_USER() EVENT event48321_2 +ON SCHEDULE AT CURRENT_TIMESTAMP +ON COMPLETION PRESERVE DISABLE +DO SELECT 48321 as BUG; +ALTER /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3 +ON SCHEDULE AT CURRENT_TIMESTAMP +ON COMPLETION PRESERVE DISABLE +DO SELECT 48321 as BUG; +Comparing tables master:test.events_view and slave:test.events_view +ALTER /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3 +ON SCHEDULE AT CURRENT_TIMESTAMP +ON COMPLETION PRESERVE DISABLE +DO SELECT 48321 as BUG; ALTER EVENT event48321_2 ENABLE | +Comparing tables master:test.events_view and slave:test.events_view +ALTER EVENT event48321_3 ENABLE; +Comparing tables master:test.events_view and slave:test.events_view +DROP EVENT event48321_4; +DROP EVENT event48321_2; +DROP EVENT event48321_3; +DROP VIEW events_view; diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result index fbfebbaa590..74ebb3be948 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result @@ -750,7 +750,7 @@ test_rpl e2 root@localhost SYSTEM RECURRING NULL 1 # # NULL ENABLED 1 latin1 lat USE test_rpl; SHOW EVENTS; Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation -test_rpl e2 @ SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci +test_rpl e2 root@localhost SYSTEM RECURRING NULL 1 # # NULL SLAVESIDE_DISABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci ==========MASTER========== SELECT COUNT(*) FROM t1; COUNT(*) @@ -1079,7 +1079,7 @@ master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 'test1') master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # use `test_rpl`; CREATE DEFINER=`root`@`localhost` EVENT e1 ON SCHEDULE EVERY '1' SECOND COMMENT 'e_second_comment' DO DELETE FROM t1 -master-bin.000001 # Query 1 # use `test_rpl`; ALTER EVENT e1 RENAME TO e2 +master-bin.000001 # Query 1 # use `test_rpl`; ALTER DEFINER=`root`@`localhost` EVENT e1 RENAME TO e2 master-bin.000001 # Query 1 # use `test_rpl`; DROP EVENT e2 master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 diff --git a/mysql-test/suite/rpl/r/rpl_sp.result b/mysql-test/suite/rpl/r/rpl_sp.result index 7fedaf4c1ef..02a5f33c843 100644 --- a/mysql-test/suite/rpl/r/rpl_sp.result +++ b/mysql-test/suite/rpl/r/rpl_sp.result @@ -433,9 +433,9 @@ master-bin.000001 # Query 1 # use `mysqltest1`; create table t2 like t1 master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `foo3`() DETERMINISTIC insert into t1 values (15) -master-bin.000001 # Query 1 # use `mysqltest1`; grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1 -master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1 -master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1 +master-bin.000001 # Query 1 # use `mysqltest1`; grant CREATE ROUTINE, EXECUTE on mysqltest1.* to 'zedjzlcsjhd'@'127.0.0.1' +master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT on mysqltest1.t1 to 'zedjzlcsjhd'@'127.0.0.1' +master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT, INSERT on mysqltest1.t2 to 'zedjzlcsjhd'@'127.0.0.1' master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`zedjzlcsjhd`@`127.0.0.1` PROCEDURE `foo4`() DETERMINISTIC begin @@ -510,7 +510,7 @@ select * from t1 master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo master-bin.000001 # Query 1 # use `mysqltest1`; drop function fn1 master-bin.000001 # Query 1 # drop database mysqltest1 -master-bin.000001 # Query 1 # drop user "zedjzlcsjhd"@127.0.0.1 +master-bin.000001 # Query 1 # DROP USER 'zedjzlcsjhd'@'127.0.0.1' master-bin.000001 # Query 1 # use `test`; drop function if exists f1 master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11) READS SQL DATA @@ -675,13 +675,13 @@ CREATE DEFINER=`root`@`localhost` PROCEDURE `foo3`() insert into t1 values (15) /*!*/; SET TIMESTAMP=t/*!*/; -grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1 +grant CREATE ROUTINE, EXECUTE on mysqltest1.* to 'zedjzlcsjhd'@'127.0.0.1' /*!*/; SET TIMESTAMP=t/*!*/; -grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1 +grant SELECT on mysqltest1.t1 to 'zedjzlcsjhd'@'127.0.0.1' /*!*/; SET TIMESTAMP=t/*!*/; -grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1 +grant SELECT, INSERT on mysqltest1.t2 to 'zedjzlcsjhd'@'127.0.0.1' /*!*/; SET TIMESTAMP=t/*!*/; CREATE DEFINER=`zedjzlcsjhd`@`127.0.0.1` PROCEDURE `foo4`() @@ -842,7 +842,7 @@ SET TIMESTAMP=t/*!*/; drop database mysqltest1 /*!*/; SET TIMESTAMP=t/*!*/; -drop user "zedjzlcsjhd"@127.0.0.1 +DROP USER 'zedjzlcsjhd'@'127.0.0.1' /*!*/; use test/*!*/; SET TIMESTAMP=t/*!*/; diff --git a/mysql-test/suite/rpl/r/rpl_user.result b/mysql-test/suite/rpl/r/rpl_user.result index a98e7e9ca55..b1f1d73cf86 100644 --- a/mysql-test/suite/rpl/r/rpl_user.result +++ b/mysql-test/suite/rpl/r/rpl_user.result @@ -39,7 +39,1754 @@ show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query # # use `test`; create user 'foo'@'fakehost' master-bin.000001 # Query # # use `test`; create user 'foo'@'fakehost', 'bar'@'fakehost' -master-bin.000001 # Query # # use `test`; rename user 'foo'@'fakehost' to 'foofoo'@'fakehost' -master-bin.000001 # Query # # use `test`; rename user 'not_exist_user1'@'fakehost' to 'foobar'@'fakehost', 'bar'@'fakehost' to 'barbar'@'fakehost' -master-bin.000001 # Query # # use `test`; drop user 'foofoo'@'fakehost' -master-bin.000001 # Query # # use `test`; drop user 'not_exist_user1'@'fakehost', 'barbar'@'fakehost' +master-bin.000001 # Query # # use `test`; RENAME USER 'foo'@'fakehost' TO 'foofoo'@'fakehost' +master-bin.000001 # Query # # use `test`; RENAME USER 'not_exist_user1'@'fakehost' TO 'foobar'@'fakehost', 'bar'@'fakehost' TO 'barbar'@'fakehost' +master-bin.000001 # Query # # use `test`; DROP USER 'foofoo'@'fakehost' +master-bin.000001 # Query # # use `test`; DROP USER 'not_exist_user1'@'fakehost', 'barbar'@'fakehost' + + + +TEST STATEMENT: 'RENAME USER $users_list' +-------------------------------------------------------------------------- +CREATE VIEW test.bug48321_v1 AS SELECT user FROM mysql.user +WHERE user LIKE 'bug48321%'; + +TEST STATEMENT: 'RENAME USER $users_list' +CASE 1: +------- +# Only CURRENT_USER() in the user list of the test statement. +users_list= CURRENT_USER() TO 'bug48321_4'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +RENAME USER CURRENT_USER() TO 'bug48321_4'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'RENAME USER $users_list' +CASE 2: +------- +# Two users are in the test statement, CURRENT_USER is the first one. +users_list= CURRENT_USER() TO 'bug48321_4'@'localhost', 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +RENAME USER CURRENT_USER() TO 'bug48321_4'@'localhost', 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'RENAME USER $users_list' +CASE 3: +------- +# Two users are in the test statement, CURRENT_USER is the last one. +users_list= 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', CURRENT_USER() TO 'bug48321_4'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +RENAME USER 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', CURRENT_USER() TO 'bug48321_4'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'RENAME USER $users_list' +CASE 4: +------- +# Three users are in the test statement, CURRENT_USER is the second one. +users_list= 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', CURRENT_USER() TO 'bug48321_4'@'localhost', 'bug48321_3'@'localhost' TO 'bug48321_6'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +RENAME USER 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', CURRENT_USER() TO 'bug48321_4'@'localhost', 'bug48321_3'@'localhost' TO 'bug48321_6'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'RENAME USER $users_list' +CASE 5: +------- +# CURRENT_USER is not in the test statement. +users_list= 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', 'bug48321_3'@'localhost' TO 'bug48321_6'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +RENAME USER 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', 'bug48321_3'@'localhost' TO 'bug48321_6'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; +DROP VIEW test.bug48321_v1; + + + +TEST STATEMENT: 'DROP USER $users_list' +-------------------------------------------------------------------------- +CREATE VIEW test.bug48321_v1 AS SELECT user FROM mysql.user +WHERE user LIKE 'bug48321%'; + +TEST STATEMENT: 'DROP USER $users_list' +CASE 1: +------- +# Only CURRENT_USER() in the user list of the test statement. +users_list= CURRENT_USER() + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +DROP USER CURRENT_USER(); + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'DROP USER $users_list' +CASE 2: +------- +# Two users are in the test statement, CURRENT_USER is the first one. +users_list= CURRENT_USER(), 'bug48321_2'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +DROP USER CURRENT_USER(), 'bug48321_2'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'DROP USER $users_list' +CASE 3: +------- +# Two users are in the test statement, CURRENT_USER is the last one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +DROP USER 'bug48321_2'@'localhost', CURRENT_USER(); + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'DROP USER $users_list' +CASE 4: +------- +# Three users are in the test statement, CURRENT_USER is the second one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +DROP USER 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'DROP USER $users_list' +CASE 5: +------- +# CURRENT_USER is not in the test statement. +users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +DROP USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; +DROP VIEW test.bug48321_v1; +DROP PROCEDURE IF EXISTS f1; +CREATE PROCEDURE p1() SELECT 1; + + + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list' +-------------------------------------------------------------------------- +CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv +FROM mysql.user WHERE user LIKE 'bug48321%'; + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list' +CASE 1: +------- +# Only CURRENT_USER() in the user list of the test statement. +users_list= CURRENT_USER() + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(); + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list' +CASE 2: +------- +# Two users are in the test statement, CURRENT_USER is the first one. +users_list= CURRENT_USER(), 'bug48321_2'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(), 'bug48321_2'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list' +CASE 3: +------- +# Two users are in the test statement, CURRENT_USER is the last one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', CURRENT_USER(); + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list' +CASE 4: +------- +# Three users are in the test statement, CURRENT_USER is the second one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list' +CASE 5: +------- +# CURRENT_USER is not in the test statement. +users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; +DROP VIEW test.bug48321_v1; + + + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/' +-------------------------------------------------------------------------- +CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv +FROM mysql.user WHERE user LIKE 'bug48321%'; + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/' +CASE 1: +------- +# Only CURRENT_USER() in the user list of the test statement. +users_list= CURRENT_USER() + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER() /*With comment*/; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/' +CASE 2: +------- +# Two users are in the test statement, CURRENT_USER is the first one. +users_list= CURRENT_USER(), 'bug48321_2'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(), 'bug48321_2'@'localhost' /*With comment*/; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/' +CASE 3: +------- +# Two users are in the test statement, CURRENT_USER is the last one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', CURRENT_USER() /*With comment*/; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/' +CASE 4: +------- +# Three users are in the test statement, CURRENT_USER is the second one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' /*With comment*/; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/' +CASE 5: +------- +# CURRENT_USER is not in the test statement. +users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' /*With comment*/; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; +DROP VIEW test.bug48321_v1; + + + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list' +-------------------------------------------------------------------------- +CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv +FROM mysql.user WHERE user LIKE 'bug48321%'; + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list' +CASE 1: +------- +# Only CURRENT_USER() in the user list of the test statement. +users_list= CURRENT_USER() + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ CURRENT_USER(); + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list' +CASE 2: +------- +# Two users are in the test statement, CURRENT_USER is the first one. +users_list= CURRENT_USER(), 'bug48321_2'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ CURRENT_USER(), 'bug48321_2'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list' +CASE 3: +------- +# Two users are in the test statement, CURRENT_USER is the last one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ 'bug48321_2'@'localhost', CURRENT_USER(); + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list' +CASE 4: +------- +# Three users are in the test statement, CURRENT_USER is the second one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list' +CASE 5: +------- +# CURRENT_USER is not in the test statement. +users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; +DROP VIEW test.bug48321_v1; + + + +TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list' +-------------------------------------------------------------------------- +CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv +FROM mysql.user WHERE user LIKE 'bug48321%'; + +TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list' +CASE 1: +------- +# Only CURRENT_USER() in the user list of the test statement. +users_list= CURRENT_USER() + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM CURRENT_USER(); + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list' +CASE 2: +------- +# Two users are in the test statement, CURRENT_USER is the first one. +users_list= CURRENT_USER(), 'bug48321_2'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM CURRENT_USER(), 'bug48321_2'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list' +CASE 3: +------- +# Two users are in the test statement, CURRENT_USER is the last one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM 'bug48321_2'@'localhost', CURRENT_USER(); + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list' +CASE 4: +------- +# Three users are in the test statement, CURRENT_USER is the second one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list' +CASE 5: +------- +# CURRENT_USER is not in the test statement. +users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; +DROP VIEW test.bug48321_v1; + + + +TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list' +-------------------------------------------------------------------------- +CREATE VIEW test.bug48321_v1 AS SELECT user, Create_routine_priv +FROM mysql.user WHERE user LIKE 'bug48321%'; + +TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list' +CASE 1: +------- +# Only CURRENT_USER() in the user list of the test statement. +users_list= CURRENT_USER() + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE CREATE ROUTINE ON *.* FROM CURRENT_USER(); + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list' +CASE 2: +------- +# Two users are in the test statement, CURRENT_USER is the first one. +users_list= CURRENT_USER(), 'bug48321_2'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE CREATE ROUTINE ON *.* FROM CURRENT_USER(), 'bug48321_2'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list' +CASE 3: +------- +# Two users are in the test statement, CURRENT_USER is the last one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE CREATE ROUTINE ON *.* FROM 'bug48321_2'@'localhost', CURRENT_USER(); + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list' +CASE 4: +------- +# Three users are in the test statement, CURRENT_USER is the second one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE CREATE ROUTINE ON *.* FROM 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list' +CASE 5: +------- +# CURRENT_USER is not in the test statement. +users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE CREATE ROUTINE ON *.* FROM 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; +DROP VIEW test.bug48321_v1; + + + +TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list' +-------------------------------------------------------------------------- +CREATE VIEW test.bug48321_v1 AS SELECT user, Routine_name, Proc_priv +FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; + +TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list' +CASE 1: +------- +# Only CURRENT_USER() in the user list of the test statement. +users_list= CURRENT_USER() + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER(); + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list' +CASE 2: +------- +# Two users are in the test statement, CURRENT_USER is the first one. +users_list= CURRENT_USER(), 'bug48321_2'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER(), 'bug48321_2'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list' +CASE 3: +------- +# Two users are in the test statement, CURRENT_USER is the last one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM 'bug48321_2'@'localhost', CURRENT_USER(); + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list' +CASE 4: +------- +# Three users are in the test statement, CURRENT_USER is the second one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list' +CASE 5: +------- +# CURRENT_USER is not in the test statement. +users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +# Grant some privileges to users at first when testing +# 'REVOKE ...' statement. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', +'bug48321_3'@'localhost' WITH GRANT OPTION; +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost', +'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; +DROP VIEW test.bug48321_v1; + + + +TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION' +-------------------------------------------------------------------------- +CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv, Password +FROM mysql.user WHERE user LIKE 'bug48321%'; + +TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION' +CASE 1: +------- +# Only CURRENT_USER() in the user list of the test statement. +users_list= CURRENT_USER() IDENTIFIED BY 'user1' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1' WITH GRANT OPTION; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION' +CASE 2: +------- +# Two users are in the test statement, CURRENT_USER is the first one. +users_list= CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost' WITH GRANT OPTION; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION' +CASE 3: +------- +# Two users are in the test statement, CURRENT_USER is the last one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1' WITH GRANT OPTION; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION' +CASE 4: +------- +# Three users are in the test statement, CURRENT_USER is the second one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '' WITH GRANT OPTION; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION' +CASE 5: +------- +# CURRENT_USER is not in the test statement. +users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '' WITH GRANT OPTION; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; +DROP VIEW test.bug48321_v1; + + + +TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION' +-------------------------------------------------------------------------- +CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv, Password +FROM mysql.user WHERE user LIKE 'bug48321%'; + +TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION' +CASE 1: +------- +# Only CURRENT_USER() in the user list of the test statement. +users_list= CURRENT_USER() IDENTIFIED BY 'user1' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1' /* With Comment */ WITH GRANT OPTION; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION' +CASE 2: +------- +# Two users are in the test statement, CURRENT_USER is the first one. +users_list= CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost' /* With Comment */ WITH GRANT OPTION; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION' +CASE 3: +------- +# Two users are in the test statement, CURRENT_USER is the last one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1' /* With Comment */ WITH GRANT OPTION; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION' +CASE 4: +------- +# Three users are in the test statement, CURRENT_USER is the second one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '' /* With Comment */ WITH GRANT OPTION; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION' +CASE 5: +------- +# CURRENT_USER is not in the test statement. +users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '' /* With Comment */ WITH GRANT OPTION; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; +DROP VIEW test.bug48321_v1; + + + +TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list' +-------------------------------------------------------------------------- +CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Password +FROM mysql.user WHERE user LIKE 'bug48321%'; + +TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list' +CASE 1: +------- +# Only CURRENT_USER() in the user list of the test statement. +users_list= CURRENT_USER() IDENTIFIED BY 'user1' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO CURRENT_USER() IDENTIFIED BY 'user1'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list' +CASE 2: +------- +# Two users are in the test statement, CURRENT_USER is the first one. +users_list= CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list' +CASE 3: +------- +# Two users are in the test statement, CURRENT_USER is the last one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list' +CASE 4: +------- +# Three users are in the test statement, CURRENT_USER is the second one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY ''; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list' +CASE 5: +------- +# CURRENT_USER is not in the test statement. +users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY ''; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; +DROP VIEW test.bug48321_v1; + + + +TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list' +-------------------------------------------------------------------------- +CREATE VIEW test.bug48321_v1 AS SELECT user, Create_routine_priv +FROM mysql.user WHERE user LIKE 'bug48321%'; + +TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list' +CASE 1: +------- +# Only CURRENT_USER() in the user list of the test statement. +users_list= CURRENT_USER() IDENTIFIED BY 'user1' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT CREATE ROUTINE ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list' +CASE 2: +------- +# Two users are in the test statement, CURRENT_USER is the first one. +users_list= CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT CREATE ROUTINE ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list' +CASE 3: +------- +# Two users are in the test statement, CURRENT_USER is the last one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT CREATE ROUTINE ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list' +CASE 4: +------- +# Three users are in the test statement, CURRENT_USER is the second one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT CREATE ROUTINE ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY ''; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list' +CASE 5: +------- +# CURRENT_USER is not in the test statement. +users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT CREATE ROUTINE ON *.* TO 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY ''; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; +DROP VIEW test.bug48321_v1; +DROP PROCEDURE p1; + + + +TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list' +-------------------------------------------------------------------------- +CREATE VIEW test.bug48321_v1 AS SELECT user, Routine_name, Proc_priv +FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; + +TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list' +CASE 1: +------- +# Only CURRENT_USER() in the user list of the test statement. +users_list= CURRENT_USER() IDENTIFIED BY 'user1' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER() IDENTIFIED BY 'user1'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list' +CASE 2: +------- +# Two users are in the test statement, CURRENT_USER is the first one. +users_list= CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list' +CASE 3: +------- +# Two users are in the test statement, CURRENT_USER is the last one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1'; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list' +CASE 4: +------- +# Three users are in the test statement, CURRENT_USER is the second one. +users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY ''; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; + +TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list' +CASE 5: +------- +# CURRENT_USER is not in the test statement. +users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '' + +# Connect to master with user1, so user1 always is the current user, +# when test statement is runing. +GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost' + WITH GRANT OPTION; +CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' + IDENTIFIED BY 'user3'; + +GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY ''; + +Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1 + +# Delete all bug48321% users +DELETE FROM mysql.user WHERE user LIKE 'bug48321%'; +DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%'; +FLUSH PRIVILEGES; +DROP VIEW test.bug48321_v1; diff --git a/mysql-test/suite/rpl/t/rpl_binlog_grant.test b/mysql-test/suite/rpl/t/rpl_binlog_grant.test index 31163927ce2..64f4e8b2eeb 100644 --- a/mysql-test/suite/rpl/t/rpl_binlog_grant.test +++ b/mysql-test/suite/rpl/t/rpl_binlog_grant.test @@ -25,9 +25,7 @@ grant select on t to x@y; # rollback; show grants for x@y; ---replace_result $VERSION VERSION ---replace_regex /\/\* xid=.* \*\//\/* XID *\// -show binlog events; +--source include/show_binlog_events.inc start transaction; insert into t values (2); revoke select on t from x@y; @@ -37,9 +35,7 @@ revoke select on t from x@y; commit; select * from t; show grants for x@y; ---replace_result $VERSION VERSION ---replace_regex /\/\* xid=.* \*\//\/* XID *\// -show binlog events; +--source include/show_binlog_events.inc drop user x@y; drop database d1; --sync_slave_with_master diff --git a/mysql-test/suite/rpl/t/rpl_events.test b/mysql-test/suite/rpl/t/rpl_events.test index 7720ad6658c..25976f779e3 100644 --- a/mysql-test/suite/rpl/t/rpl_events.test +++ b/mysql-test/suite/rpl/t/rpl_events.test @@ -105,3 +105,85 @@ DROP EVENT event44331_2; DROP EVENT event44331_3; DROP EVENT event44331_4; sync_slave_with_master; + +# +# BUG#48321 +# This test verifies if the definer is consistent between master and slave, +# when the event is created or altered with the DEFINER clause that the +# DEFINER is set to CURRENT_USER() +# +connection master; +--disable_warnings +DROP VIEW IF EXISTS events_view; +DROP EVENT IF EXISTS event48321_1; +DROP EVENT IF EXISTS event48321_2; +DROP EVENT IF EXISTS event48321_3; +DROP EVENT IF EXISTS event48321_4; +--enable_warnings + +CREATE VIEW events_view AS + SELECT EVENT_SCHEMA, EVENT_NAME, DEFINER FROM INFORMATION_SCHEMA.EVENTS + WHERE EVENT_NAME LIKE 'event48321%'; +let $diff_table_1= master:test.events_view; +let $diff_table_2= slave:test.events_view; + +CREATE DEFINER=CURRENT_USER() /*!50000 EVENT event48321_1 */ + ON SCHEDULE AT CURRENT_TIMESTAMP + ON COMPLETION PRESERVE DISABLE + DO SELECT 48321 as BUG; + +CREATE DEFINER=CURRENT_USER() EVENT event48321_2 + ON SCHEDULE AT CURRENT_TIMESTAMP + ON COMPLETION PRESERVE DISABLE + DO SELECT 48321 as BUG; + +CREATE /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3 + ON SCHEDULE AT CURRENT_TIMESTAMP + ON COMPLETION PRESERVE DISABLE + DO SELECT 48321 as BUG; +sync_slave_with_master; + +--source include/diff_tables.inc + +connection master; +ALTER DEFINER=CURRENT_USER() EVENT event48321_1 RENAME TO event48321_4; + +ALTER DEFINER=CURRENT_USER() EVENT event48321_2 + ON SCHEDULE AT CURRENT_TIMESTAMP + ON COMPLETION PRESERVE DISABLE + DO SELECT 48321 as BUG; + +ALTER /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3 + ON SCHEDULE AT CURRENT_TIMESTAMP + ON COMPLETION PRESERVE DISABLE + DO SELECT 48321 as BUG; +sync_slave_with_master; + +--source include/diff_tables.inc + +# Two statements in on query +connection master; +DELIMITER |; +ALTER /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3 + ON SCHEDULE AT CURRENT_TIMESTAMP + ON COMPLETION PRESERVE DISABLE + DO SELECT 48321 as BUG; ALTER EVENT event48321_2 ENABLE | +DELIMITER ;| +sync_slave_with_master; + +--source include/diff_tables.inc + +#No Event boday +connection master; +ALTER EVENT event48321_3 ENABLE; +sync_slave_with_master; + +--source include/diff_tables.inc + +connection master; +DROP EVENT event48321_4; +DROP EVENT event48321_2; +DROP EVENT event48321_3; +DROP VIEW events_view; +--source include/master-slave-end.inc + diff --git a/mysql-test/suite/rpl/t/rpl_user.test b/mysql-test/suite/rpl/t/rpl_user.test index b8fe41d03c4..2adb822839a 100644 --- a/mysql-test/suite/rpl/t/rpl_user.test +++ b/mysql-test/suite/rpl/t/rpl_user.test @@ -54,8 +54,85 @@ drop user 'not_exist_user1'@'fakehost', 'not_exist_user2'@'fakehost'; sync_slave_with_master; select Host,User from mysql.user where Host='fakehost'; -# -# show the binlog events on the master -# connection master; source include/show_binlog_events.inc; + +# +# BUG#48321 +# +let $action= RENAME; +let $statement= RENAME USER \$users_list; +source extra/rpl_tests/rpl_current_user.test; + +let $action= DROP; +let $statement= DROP USER \$users_list; +source extra/rpl_tests/rpl_current_user.test; + +--disable_warnings +DROP PROCEDURE IF EXISTS f1; +--enable_warnings +CREATE PROCEDURE p1() SELECT 1; +#REVOKE ALL PRIVILEGES +let $action= REVOKE; +let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv; +let $statement= REVOKE ALL PRIVILEGES, GRANT OPTION FROM \$users_list; +source extra/rpl_tests/rpl_current_user.test; + +#REVOKE ALL PRIVILEGES with comment +let $action= REVOKE; +let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv; +let $statement= REVOKE ALL PRIVILEGES, GRANT OPTION FROM \$users_list /*With comment*/; +source extra/rpl_tests/rpl_current_user.test; + +#REVOKE ALL PRIVILEGES with comment +let $action= REVOKE; +let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv; +let $statement= REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ \$users_list; +source extra/rpl_tests/rpl_current_user.test; + +let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv; +#REVOKE ON TABLE +let $statement= REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM \$users_list; +source extra/rpl_tests/rpl_current_user.test; + +#REVOKE ON CREATE ROUTINE +let $diff_columns= Create_routine_priv; +let $statement= REVOKE CREATE ROUTINE ON *.* FROM \$users_list; +source extra/rpl_tests/rpl_current_user.test; + +#REVOKE ON ROUTINE +let $diff_table= mysql.procs_priv; +let $diff_columns= Routine_name, Proc_priv; +let $statement= REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM \$users_list; +source extra/rpl_tests/rpl_current_user.test; + +let $diff_table= mysql.user; +#GRANT ALL PRIVILEGES +let $action= GRANT; +let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv, Password; +let $statement= GRANT ALL PRIVILEGES ON *.* TO \$users_list WITH GRANT OPTION; +source extra/rpl_tests/rpl_current_user.test; + +#GRANT ALL PRIVILEGES with comment +let $action= GRANT; +let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv, Password; +let $statement= GRANT ALL PRIVILEGES ON *.* TO \$users_list /* With Comment */ WITH GRANT OPTION; +source extra/rpl_tests/rpl_current_user.test; + +#GRANT ON TABLE +let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Password; +let $statement= GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO \$users_list; +source extra/rpl_tests/rpl_current_user.test; + +#GRANT ON CREATE ROUTINE +let $diff_columns= Create_routine_priv; +let $statement= GRANT CREATE ROUTINE ON *.* TO \$users_list; +source extra/rpl_tests/rpl_current_user.test; + +#GRANT ON ROUTINE +let $diff_table= mysql.procs_priv; +let $diff_columns= Routine_name, Proc_priv; +let $statement= GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO \$users_list; + +DROP PROCEDURE p1; +source extra/rpl_tests/rpl_current_user.test; diff --git a/sql/events.cc b/sql/events.cc index 4c6dd0f35d1..6c8bdb1ea0f 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -341,31 +341,48 @@ common_1_lev_code: } -/** - Create a new query string for removing executable comments - for avoiding leak and keeping consistency of the execution - on master and slave. - +/* + Binlog '{CREATE|ALTER} EVENT' statements. + Definer part is always rewritten, for definer can be CURRENT_USER() function. + @param[in] thd Thread handler - @param[in] buf Query string + @param[in] create CREATE or ALTER statement @return - 0 ok - 1 error + FASE ok + TRUE error */ -static int -create_query_string(THD *thd, String *buf) +static bool event_write_bin_log(THD *thd, bool create) { - /* Append the "CREATE" part of the query */ - if (buf->append(STRING_WITH_LEN("CREATE "))) - return 1; - /* Append definer */ - append_definer(thd, buf, &(thd->lex->definer->user), &(thd->lex->definer->host)); + String log_query; + if (create) + { + /* Append the "CREATE" part of the query */ + if (log_query.append(STRING_WITH_LEN("CREATE "))) + return TRUE; + } + else + { + /* Append the "ALETR " part of the query */ + if (log_query.append(STRING_WITH_LEN("ALTER "))) + return TRUE; + } + + /* Append definer + If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER + will be written into the binary log as the definer for the SQL thread. + */ + append_definer(thd, &log_query, &(thd->lex->definer->user), + &(thd->lex->definer->host)); + /* Append the left part of thd->query after "DEFINER" part */ - if (buf->append(thd->lex->stmt_definition_begin)) - return 1; - - return 0; + if (log_query.append(thd->lex->stmt_definition_begin, + thd->lex->stmt_definition_end - + thd->lex->stmt_definition_begin)) + return TRUE; + + return write_bin_log(thd, TRUE, log_query.c_ptr_safe(), log_query.length()) + != 0; } /** @@ -380,8 +397,7 @@ create_query_string(THD *thd, String *buf) @sa Events::drop_event for the notes about locking, pre-locking and Events DDL. - @retval FALSE OK - @retval TRUE Error (reported) + @retval FALSE OK @retval TRUE Error (reported) */ bool @@ -465,22 +481,7 @@ Events::create_event(THD *thd, Event_parse_data *parse_data, binlog the create event unless it's been successfully dropped */ if (!dropped) - { - /* Binlog the create event. */ - DBUG_ASSERT(thd->query() && thd->query_length()); - String log_query; - if (create_query_string(thd, &log_query)) - { - sql_print_error("Event Error: An error occurred while creating query string, " - "before writing it into binary log."); - /* Restore the state of binlog format */ - thd->current_stmt_binlog_row_based= save_binlog_row_based; - DBUG_RETURN(TRUE); - } - /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER - will be written into the binary log as the definer for the SQL thread. */ - ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length()); - } + ret= event_write_bin_log(thd, TRUE); } pthread_mutex_unlock(&LOCK_event_metadata); /* Restore the state of binlog format */ @@ -602,9 +603,7 @@ Events::update_event(THD *thd, Event_parse_data *parse_data, if (event_queue) event_queue->update_event(thd, parse_data->dbname, parse_data->name, new_element); - /* Binlog the alter event. */ - DBUG_ASSERT(thd->query() && thd->query_length()); - ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + ret= event_write_bin_log(thd, FALSE); } } pthread_mutex_unlock(&LOCK_event_metadata); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index a8828d15cae..70983f69746 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -194,6 +194,7 @@ static bool compare_hostname(const acl_host_and_ip *host,const char *hostname, const char *ip); static my_bool acl_load(THD *thd, TABLE_LIST *tables); static my_bool grant_load(THD *thd, TABLE_LIST *tables); +static bool acl_write_bin_log(THD *thd, List &list, bool clear_error); /* Convert scrambled password to binary form, according to scramble type, @@ -3225,7 +3226,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, if (!result) /* success */ { - result= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + if (acl_write_bin_log(thd, user_list, TRUE)) + result= -1; } rw_unlock(&LOCK_grant); @@ -3401,8 +3403,7 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, if (write_to_binlog) { - if (write_bin_log(thd, FALSE, thd->query(), thd->query_length())) - result= TRUE; + result|= acl_write_bin_log(thd, user_list, FALSE); } rw_unlock(&LOCK_grant); @@ -3531,7 +3532,7 @@ bool mysql_grant(THD *thd, const char *db, List &list, if (!result) { - result= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); + result= acl_write_bin_log(thd, list, TRUE); } rw_unlock(&LOCK_grant); @@ -5663,9 +5664,9 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop, } -static void append_user(String *str, LEX_USER *user) +static void append_user(String *str, LEX_USER *user, bool comma= TRUE) { - if (str->length()) + if (comma && str->length()) str->append(','); str->append('\''); str->append(user->user.str); @@ -5674,6 +5675,65 @@ static void append_user(String *str, LEX_USER *user) str->append('\''); } +/* + The operations(DROP, RENAME, REVOKE, GRANT) will cause inconsistency between + master and slave, when CURRENT_USER() is used. To solve this problem, we + construct a new binlog statement in which CURRENT_USER() is replaced by + the real user name and host name. + */ +static bool acl_write_bin_log(THD *thd, List &list, bool clear_error) +{ + String log_query; + LEX *lex= thd->lex; + List_iterator user_list(list); + LEX_USER *user, *tmp_user; + + if (!mysql_bin_log.is_open()) + return FALSE; + + if (log_query.append(lex->stmt_begin, lex->stmt_user_begin - lex->stmt_begin)) + return TRUE; + while ((tmp_user= user_list++)) + { + if (!(user= get_current_user(thd, tmp_user))) + continue; + + /* + No User, but a password? + They did GRANT ... TO CURRENT_USER() IDENTIFIED BY ... ! + Get the current user, and shallow-copy the new password to them! + */ + if (!tmp_user->user.str && tmp_user->password.str) + user->password= tmp_user->password; + + if (log_query.append(" ", 1)) + return TRUE; + append_user(&log_query, user, FALSE); + /* Only 'GRANT' have password */ + if (user->password.str) + { + if (log_query.append(STRING_WITH_LEN(" IDENTIFIED BY ")) || + log_query.append(STRING_WITH_LEN("PASSWORD ")) || + log_query.append("'", 1) || + log_query.append(user->password.str, + user->password.length) || + log_query.append("'", 1)) + return TRUE; + } + if (log_query.append(",", 1)) + return TRUE; + } + /* It is binlogged only when at least one user is in the query */ + if (log_query.c_ptr()[log_query.length()-1] == ',') + { + log_query.length(log_query.length()-1); + if (log_query.append(lex->stmt_user_end, lex->stmt_end - lex->stmt_user_end)) + return TRUE; + return write_bin_log(thd, clear_error, log_query.c_ptr_safe(), + log_query.length()) != 0; + } + return FALSE; +} /* Create a list of users. @@ -5780,6 +5840,7 @@ bool mysql_drop_user(THD *thd, List &list) { int result; String wrong_users; + String log_query; LEX_USER *user_name, *tmp_user_name; List_iterator user_list(list); TABLE_LIST tables[GRANT_TABLES]; @@ -5809,6 +5870,7 @@ bool mysql_drop_user(THD *thd, List &list) rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); + log_query.append(STRING_WITH_LEN("DROP USER")); while ((tmp_user_name= user_list++)) { if (!(user_name= get_current_user(thd, tmp_user_name))) @@ -5816,6 +5878,17 @@ bool mysql_drop_user(THD *thd, List &list) result= TRUE; continue; } + + /* + The operation will cause inconsistency between master and slave, when + CURRENT_USER() is used. To solve this problem, we construct a new + binlog statement in which CURRENT_USER() is replaced by the real user + name and host name. + */ + log_query.append(STRING_WITH_LEN(" ")); + append_user(&log_query, user_name, FALSE); + log_query.append(STRING_WITH_LEN(",")); + if (handle_grant_data(tables, 1, user_name, NULL) <= 0) { append_user(&wrong_users, user_name); @@ -5834,7 +5907,13 @@ bool mysql_drop_user(THD *thd, List &list) my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe()); if (some_users_deleted) - result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length()); + { + if (log_query.c_ptr()[log_query.length()-1] == ',') + { + log_query.length(log_query.length()-1); + result|= write_bin_log(thd, FALSE, log_query.c_ptr_safe(), log_query.length()); + } + } rw_unlock(&LOCK_grant); close_thread_tables(thd); @@ -5862,6 +5941,7 @@ bool mysql_rename_user(THD *thd, List &list) { int result; String wrong_users; + String log_query; LEX_USER *user_from, *tmp_user_from; LEX_USER *user_to, *tmp_user_to; List_iterator user_list(list); @@ -5889,6 +5969,7 @@ bool mysql_rename_user(THD *thd, List &list) rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); + log_query.append(STRING_WITH_LEN("RENAME USER")); while ((tmp_user_from= user_list++)) { if (!(user_from= get_current_user(thd, tmp_user_from))) @@ -5904,6 +5985,18 @@ bool mysql_rename_user(THD *thd, List &list) } DBUG_ASSERT(user_to != 0); /* Syntax enforces pairs of users. */ + /* + The operation will cause inconsistency between master and slave, when + CURRENT_USER() is used. To solve this problem, we construct a new + binlog statement in which CURRENT_USER() is replaced by the real user + name and host name. + */ + log_query.append(STRING_WITH_LEN(" ")); + append_user(&log_query, user_from, FALSE); + log_query.append(STRING_WITH_LEN(" TO ")); + append_user(&log_query, user_to, FALSE); + log_query.append(STRING_WITH_LEN(",")); + /* Search all in-memory structures and grant tables for a mention of the new user name. @@ -5925,9 +6018,15 @@ bool mysql_rename_user(THD *thd, List &list) if (result) my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe()); - - if (some_users_renamed && mysql_bin_log.is_open()) - result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length()); + + if (some_users_renamed) + { + if (log_query.c_ptr()[log_query.length()-1] == ',') + { + log_query.length(log_query.length()-1); + result|= write_bin_log(thd, FALSE, log_query.c_ptr_safe(), log_query.length()); + } + } rw_unlock(&LOCK_grant); close_thread_tables(thd); @@ -6117,8 +6216,9 @@ bool mysql_revoke_all(THD *thd, List &list) VOID(pthread_mutex_unlock(&acl_cache->lock)); - int binlog_error= - write_bin_log(thd, FALSE, thd->query(), thd->query_length()); + int binlog_error= 0; + if (acl_write_bin_log(thd, list, FALSE)) + binlog_error= 1; rw_unlock(&LOCK_grant); close_thread_tables(thd); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 4e4794ef2cf..99f5257eb5e 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1727,6 +1727,8 @@ typedef struct st_lex : public Query_tables_list - CREATE TRIGGER (points to "TRIGGER"); - CREATE PROCEDURE (points to "PROCEDURE"); - CREATE FUNCTION (points to "FUNCTION" or "AGGREGATE"); + - CREATE VIEW(points to "VIEW"); + - CREATE EVENT(points to "EVENT"); This pointer is required to add possibly omitted DEFINER-clause to the DDL-statement before dumping it to the binlog. @@ -1735,6 +1737,29 @@ typedef struct st_lex : public Query_tables_list const char *stmt_definition_end; + /* + stmt_begin is intended to point to the begin of every statement. + It is now used in the following statements: + - GRANT ALL PRIVELEGES ON *.* (points to "GRANT"); + - REVOKE ALL PRIVELEGES ON *.* (points to "REVOKE"); + */ + const char *stmt_begin; + const char *stmt_end; + + /* + stmt_user_begin is intended to point to the begin of the user list in + the following statements: + - GRANT ALL PRIVELEGES ON *.* TO 'username'@'hostname' + (points to "'username'"); + - REVOKE ALL PRIVELEGES ON *.* FROM 'username'@'hostname' + (points to "'username'"); + + these pointers are required to replace the CURRENT_USER() + function by the real user before dumping it to the binlog. + */ + const char *stmt_user_begin; + const char *stmt_user_end; + /** During name resolution search only in the table list given by Name_resolution_context::first_name_resolution_table and diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 8dc08f8425f..92c4de5b462 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1562,7 +1562,11 @@ opt_end_of_input: ; verb_clause: - statement + remember_name statement remember_end + { + Lex->stmt_begin= $1; + Lex->stmt_end= $3; + } | begin ; @@ -5743,7 +5747,7 @@ alter: } view_tail {} - | ALTER definer_opt EVENT_SYM sp_name + | ALTER definer_opt remember_name EVENT_SYM sp_name { /* It is safe to use Lex->spname because @@ -5755,7 +5759,8 @@ alter: if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD))) MYSQL_YYABORT; - Lex->event_parse_data->identifier= $4; + Lex->event_parse_data->identifier= $5; + Lex->stmt_definition_begin= $3; Lex->sql_command= SQLCOM_ALTER_EVENT; } @@ -5765,7 +5770,7 @@ alter: opt_ev_comment opt_ev_sql_stmt { - if (!($6 || $7 || $8 || $9 || $10)) + if (!($7 || $8 || $9 || $10 || $11)) { my_parse_error(ER(ER_SYNTAX_ERROR)); MYSQL_YYABORT; @@ -5826,7 +5831,16 @@ opt_ev_rename_to: ; opt_ev_sql_stmt: - /* empty*/ { $$= 0;} + /* empty*/ + { + $$= 0; + /* + Lex->sp_head is not initialized when event body is empty. + So we can not use Lex->sp_head->set_stmt_end() to set + stmt_definition_end. + */ + Lex->stmt_definition_end= (char*) YYLIP->get_cpp_tok_end(); + } | DO_SYM ev_sql_stmt { $$= 1; } ; @@ -11516,6 +11530,7 @@ user: $$->user = $1; $$->host.str= (char *) "%"; $$->host.length= 1; + Lex->stmt_user_end= YYLIP->get_cpp_ptr(); if (check_string_char_length(&$$->user, ER(ER_USERNAME), USERNAME_CHAR_LENGTH, @@ -11528,6 +11543,7 @@ user: if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user)))) MYSQL_YYABORT; $$->user = $1; $$->host=$3; + Lex->stmt_user_end= YYLIP->get_cpp_ptr(); if (check_string_char_length(&$$->user, ER(ER_USERNAME), USERNAME_CHAR_LENGTH, @@ -11537,6 +11553,7 @@ user: } | CURRENT_USER optional_braces { + Lex->stmt_user_end= YYLIP->get_cpp_ptr(); if (!($$=(LEX_USER*) YYTHD->alloc(sizeof(st_lex_user)))) MYSQL_YYABORT; /* @@ -12727,9 +12744,10 @@ user_list: ; grant_list: + { Lex->stmt_user_begin= YYLIP->get_cpp_ptr(); } grant_user { - if (Lex->users_list.push_back($1)) + if (Lex->users_list.push_back($2)) MYSQL_YYABORT; } | grant_list ',' grant_user @@ -12742,6 +12760,7 @@ grant_list: grant_user: user IDENTIFIED_SYM BY TEXT_STRING { + Lex->stmt_user_end= YYLIP->get_cpp_ptr(); $$=$1; $1->password=$4; if ($4.length) { @@ -12768,7 +12787,10 @@ grant_user: } } | user IDENTIFIED_SYM BY PASSWORD TEXT_STRING - { $$= $1; $1->password= $5; } + { + Lex->stmt_user_end= YYLIP->get_cpp_ptr(); + $$= $1; $1->password= $5; + } | user { $$= $1; $1->password= null_lex_str; } ; From 1ff667c995a1a597615a9fb4820218d48659ae71 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 1 Feb 2010 13:40:16 +0200 Subject: [PATCH 150/157] fixed a typo in bug #49897. --- sql/sql_select.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 239809f1d4c..eecc2b086a3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -531,7 +531,7 @@ JOIN::prepare(Item ***rref_pointer_array, there. Such fields don't contain any data to sort. */ if (!real_order && - (item->type() != Item::Item::FIELD_ITEM || + (item->type() != Item::FIELD_ITEM || ((Item_field *) item)->field->maybe_null() || ((Item_field *) item)->field->sort_length())) real_order= TRUE; From 9b75c2f268f0e40fe74f38759c8f8551b2637145 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Mon, 1 Feb 2010 14:05:21 +0200 Subject: [PATCH 151/157] Made outfile_testdata experimental in 5.1-bugteam, pending the resulution of bug #46895. --- mysql-test/collections/default.experimental | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 9c4055cd19e..d791686cd62 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -14,6 +14,7 @@ funcs_2.ndb_charset # joro : NDB tests marked as experiment main.ctype_gbk_binlog @solaris # Bug#46010: main.ctype_gbk_binlog fails sporadically : Table 't2' already exists main.plugin_load @solaris # Bug#42144 +main.outfile_loaddata @solaris # joro : Bug #46895 ndb.* # joro : NDB tests marked as experimental as agreed with bochklin From 56b911f893594004c2da92c9a77b2f122fe317d9 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Tue, 2 Feb 2010 15:16:47 +0000 Subject: [PATCH 152/157] BUG#47639: The rpl_binlog_corruption test fails on Windows The test case rpl_binlog_corruption fails on windows because when adding a line to the binary log index file it gets terminated with a CR+LF (which btw, is the normal case in windows, but not on Unixes - LF). This causes mismatch between the relay log names, causing mysqld to report that it cannot find the log file. We fix this by creating the instrumented index file through mysql, ie, using SELECT ... INTO DUMPFILE ..., as opposed on relying on ultimatly OS commands like: -- echo "..." > index. These changes go into the file and make the procedure platform independent: include/setup_fake_relay_log.inc Side note: when using SELECT ... INTO DUMPFILE ..., one needs to check if mysqld is running with secure_file_priv. If it is, we do it in two steps: 1. create the file on the allowed location; 2. move it to the datadir. If it is not, then we just create the file directly on the datadir (so previous step 2. is not needed). --- mysql-test/include/setup_fake_relay_log.inc | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/mysql-test/include/setup_fake_relay_log.inc b/mysql-test/include/setup_fake_relay_log.inc index f88806e1079..5b9e7f72fdd 100644 --- a/mysql-test/include/setup_fake_relay_log.inc +++ b/mysql-test/include/setup_fake_relay_log.inc @@ -69,7 +69,22 @@ let $_fake_relay_log_purge= `SELECT @@global.relay_log_purge`; # Create relay log file. copy_file $fake_relay_log $_fake_relay_log; # Create relay log index. ---exec echo $_fake_filename-fake.000001 > $_fake_relay_index + +if (`SELECT LENGTH(@@secure_file_priv) > 0`) +{ + -- let $_file_priv_dir= `SELECT @@secure_file_priv`; + -- let $_suffix= `SELECT UUID()` + -- let $_tmp_file= $_file_priv_dir/fake-index.$_suffix + + -- eval select '$_fake_filename-fake.000001\n' into dumpfile '$_tmp_file' + -- copy_file $_tmp_file $_fake_relay_index + -- remove_file $_tmp_file +} + +if (`SELECT LENGTH(@@secure_file_priv) = 0`) +{ + -- eval select '$_fake_filename-fake.000001\n' into dumpfile '$_fake_relay_index' +} # Setup replication from existing relay log. eval CHANGE MASTER TO MASTER_HOST='dummy.localdomain', RELAY_LOG_FILE='$_fake_filename-fake.000001', RELAY_LOG_POS=4; From 673ec7b24d1e4c8806d964ef262f39fadc84da70 Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Tue, 2 Feb 2010 23:29:14 +0100 Subject: [PATCH 153/157] Changes to be able to create source TAR packages with longer path names than 99 characters, using the USTAR format of the resulting source TAR. To be able to specify the use of USTAR when creating the source TAR, we needed both to update the GNU autotools version requirements slightly, and update the initiation of the tools to use more modern constructs. --- configure.in | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/configure.in b/configure.in index 38eb511ac18..eeb1da8670a 100644 --- a/configure.in +++ b/configure.in @@ -1,17 +1,23 @@ dnl -*- ksh -*- dnl Process this file with autoconf to produce a configure script. -AC_PREREQ(2.52)dnl Minimum Autoconf version required. +# Minimum Autoconf version required. +AC_PREREQ(2.59) -AC_INIT(sql/mysqld.cc) -AC_CANONICAL_SYSTEM -# The Docs Makefile.am parses this line! -# remember to also update version.c in ndb -# +# Remember to also update version.c in ndb. # When changing major version number please also check switch statement # in mysqlbinlog::check_master_version(). -AM_INIT_AUTOMAKE(mysql, 5.1.43) -AM_CONFIG_HEADER([include/config.h:config.h.in]) +AC_INIT([MySQL Server], [5.1.43], [], [mysql]) +AC_CONFIG_SRCDIR([sql/mysqld.cc]) +AC_CANONICAL_SYSTEM +# USTAR format gives us the possibility to store longer path names in +# TAR files, the path name is split into two parts, a 155 chacater +# first part and a 100 character second part. +AM_INIT_AUTOMAKE([1.9 tar-ustar]) +LT_INIT +LT_PREREQ([1.5.6]) + +AM_CONFIG_HEADER([include/config.h]) # Request support for automake silent-rules if available. # Default to verbose output. One can use the configure-time From 0a90bfe6c019fd1dc3db3090de969077ac311fb5 Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Wed, 3 Feb 2010 14:52:11 +0100 Subject: [PATCH 154/157] Adjuster the parsing of "configure.in" version number line --- win/configure.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/win/configure.js b/win/configure.js index fc5c548c983..38fa8e7afeb 100644 --- a/win/configure.js +++ b/win/configure.js @@ -140,11 +140,11 @@ function GetValue(str, key) function GetVersion(str) { - var key = "AM_INIT_AUTOMAKE(mysql, "; - var pos = str.indexOf(key); //5.0.6-beta) + var key = "AC_INIT([MySQL Server], ["; + var pos = str.indexOf(key); if (pos == -1) return null; pos += key.length; - var end = str.indexOf(")", pos); + var end = str.indexOf("]", pos); if (end == -1) return null; return str.substring(pos, end); } From b8db15fc226063b83e507fcdfec1765088abcada Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 4 Feb 2010 12:13:29 +0200 Subject: [PATCH 155/157] tree name change --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 557df1b1ffe..f79c1cd6319 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.0-bugteam" +tree_name = "mysql-5.0" From 62db6839b82d824567979ef3e05caccd67ed11ec Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 17 Feb 2010 18:39:28 +0100 Subject: [PATCH 156/157] configure.in - Changes to the banner text - Use older AC_PROG_LIBTOOL (Bug#51009) scripts/mysql_install_db.sh - Changes to banner text --- configure.in | 20 +++++++------------- scripts/mysql_install_db.sh | 6 +----- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/configure.in b/configure.in index f2e83abc60c..32326df06aa 100644 --- a/configure.in +++ b/configure.in @@ -14,8 +14,7 @@ AC_CANONICAL_SYSTEM # TAR files, the path name is split into two parts, a 155 chacater # first part and a 100 character second part. AM_INIT_AUTOMAKE([1.9 tar-ustar]) -LT_INIT -LT_PREREQ([1.5.6]) +AC_PROG_LIBTOOL AM_CONFIG_HEADER([include/config.h]) @@ -2912,17 +2911,12 @@ AC_CONFIG_COMMANDS_POST(ac_configure_args="$ac_configure_args CFLAGS='$CFLAGS' C AC_OUTPUT -echo -echo "MySQL has a Web site at http://www.mysql.com/ which carries details on the" -echo "latest release, upcoming features, and other information to make your" -echo "work or play with MySQL more productive. There you can also find" -echo "information about mailing lists for MySQL discussion." -echo -echo "Remember to check the platform specific part of the reference manual for" -echo "hints about installing MySQL on your platform. Also have a look at the" -echo "files in the Docs directory." -echo -# The following text is checked in ./Do-compile to verify that configure +# The first line "Thank you ..." is checked in ./Do-compile to verify that configure # ended sucessfully - don't remove it. +echo echo "Thank you for choosing MySQL!" echo +echo "Remember to check the platform specific part of the reference manual" +echo "for hints about installing MySQL on your platform." +echo "Also have a look at the files in the Docs directory." +echo diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 20b7973cb4e..c5e4a1f1cba 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -410,8 +410,7 @@ else echo "Try 'mysqld --help' if you have problems with paths. Using --log" echo "gives you a log in $ldata that may be helpful." echo - echo "The latest information about MySQL is available on the web at" - echo "http://www.mysql.com/. Please consult the MySQL manual section" + echo "Please consult the MySQL manual section" echo "'Problems running mysql_install_db', and the manual section that" echo "describes problems on your OS. Another information source are the" echo "MySQL email archives available at http://lists.mysql.com/." @@ -470,9 +469,6 @@ then echo echo "Please report any problems with the $scriptdir/mysqlbug script!" echo - echo "The latest information about MySQL is available at http://www.mysql.com/" - echo "Support MySQL by buying support/licenses from http://shop.mysql.com/" - echo fi exit 0 From c9dffa993a845752a847c4fe36c99cc6adbc35a8 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 9 Mar 2010 16:03:54 +0100 Subject: [PATCH 157/157] A number of after-merge fixes following merge of MySQL 5.1.44 into MariaDB. Bug#46949: memory leak with failed alter table to create partitions based on extract() Bug#51830: Incorrect partition pruning on range partition (regression) Fixed valgrind failure in select_describe(), read of uninitialized Item_subselect::eliminated. PBXT test file updates to reflect changes done in MySQL. mysql-test/suite/pbxt/r/partition_error.result: Result file update following MySQL 5.1.44 changes. mysql-test/suite/pbxt/r/partition_pruning.result: Result file update following MySQL 5.1.44 changes. mysql-test/suite/pbxt/t/partition_error.test: Test file update following MySQL 5.1.44 changes. sql/item_subselect.cc: Fixed valgrind failure in select_describe(), read of uninitialized Item_subselect::eliminated: - it turns out we can call select_describe() without having fixed subquery items for child subselects. These are not the kind of subqueries that we could eliminate, so the fix is to ensure that item_subselect->eliminated==FALSE even before fix_fields is called. Also added code to reset item_subselect->eliminated back to FALSE in Item::reset() call. sql/item_subselect.h: Fixed valgrind failure in select_describe(), read of uninitialized Item_subselect::eliminated: - it turns out we can call select_describe() without having fixed subquery items for child subselects. These are not the kind of subqueries that we could eliminate, so the fix is to ensure that item_subselect->eliminated==FALSE even before fix_fields is called. Also added code to reset item_subselect->eliminated back to FALSE in Item::reset() call. sql/sql_partition.cc: Fix Bug#51830: Revert part of the patch for Bug#49742, which caused the regression. sql/table.cc: Fix Bug#46949: memory leak in failed ALTER TABLE with partitioning. --- mysql-test/suite/pbxt/r/partition_error.result | 18 +++++++++--------- .../suite/pbxt/r/partition_pruning.result | 2 +- mysql-test/suite/pbxt/t/partition_error.test | 4 ++-- sql/item_subselect.cc | 4 +++- sql/item_subselect.h | 3 +++ sql/sql_partition.cc | 5 +++-- sql/table.cc | 2 +- 7 files changed, 22 insertions(+), 16 deletions(-) diff --git a/mysql-test/suite/pbxt/r/partition_error.result b/mysql-test/suite/pbxt/r/partition_error.result index af708fb01b0..a36d0bddabb 100644 --- a/mysql-test/suite/pbxt/r/partition_error.result +++ b/mysql-test/suite/pbxt/r/partition_error.result @@ -107,7 +107,7 @@ primary key(a,b)) partition by hash (rand(a)) partitions 2 (partition x1, partition x2); -ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ') +ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ') partitions 2 (partition x1, partition x2)' at line 6 CREATE TABLE t1 ( @@ -118,7 +118,7 @@ primary key(a,b)) partition by range (rand(a)) partitions 2 (partition x1 values less than (0), partition x2 values less than (2)); -ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ') +ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ') partitions 2 (partition x1 values less than (0), partition x2 values less than' at line 6 CREATE TABLE t1 ( @@ -129,7 +129,7 @@ primary key(a,b)) partition by list (rand(a)) partitions 2 (partition x1 values in (1), partition x2 values in (2)); -ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ') +ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ') partitions 2 (partition x1 values in (1), partition x2 values in (2))' at line 6 CREATE TABLE t1 ( @@ -244,7 +244,7 @@ c int not null, primary key (a,b)) partition by key (a) subpartition by hash (rand(a+b)); -ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 7 +ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')' at line 7 CREATE TABLE t1 ( a int not null, b int not null, @@ -341,7 +341,7 @@ partition by range (3+4) partitions 2 (partition x1 values less than (4) tablespace ts1, partition x2 values less than (8) tablespace ts2); -ERROR HY000: Constant/Random expression in (sub)partitioning function is not allowed +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed CREATE TABLE t1 ( a int not null, b int not null, @@ -511,7 +511,7 @@ partition by list (3+4) partitions 2 (partition x1 values in (4) tablespace ts1, partition x2 values in (8) tablespace ts2); -ERROR HY000: Constant/Random expression in (sub)partitioning function is not allowed +ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed CREATE TABLE t1 ( a int not null, b int not null, @@ -603,13 +603,13 @@ partition by range (ascii(v)) ERROR HY000: This partition function is not allowed create table t1 (a int) partition by hash (rand(a)); -ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2 +ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')' at line 2 create table t1 (a int) partition by hash(CURTIME() + a); -ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2 +ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')' at line 2 create table t1 (a int) partition by hash (NOW()+a); -ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2 +ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')' at line 2 create table t1 (a int) partition by hash (extract(hour from convert_tz(a, '+00:00', '+00:00'))); ERROR HY000: This partition function is not allowed diff --git a/mysql-test/suite/pbxt/r/partition_pruning.result b/mysql-test/suite/pbxt/r/partition_pruning.result index 9938d352ff7..2f43fa6eb86 100644 --- a/mysql-test/suite/pbxt/r/partition_pruning.result +++ b/mysql-test/suite/pbxt/r/partition_pruning.result @@ -527,7 +527,7 @@ id select_type table partitions type possible_keys key key_len ref rows Extra 1 SIMPLE t2 p0,p4 ALL NULL NULL NULL NULL 910 Using where explain partitions select * from t2 where (a > 100 AND a < 600); id select_type table partitions type possible_keys key key_len ref rows Extra -1 SIMPLE t2 p0,p1,p2,p3 ALL NULL NULL NULL NULL 910 Using where +1 SIMPLE t2 p0,p1,p2 ALL NULL NULL NULL NULL 910 Using where analyze table t2; Table Op Msg_type Msg_text test.t2 analyze status OK diff --git a/mysql-test/suite/pbxt/t/partition_error.test b/mysql-test/suite/pbxt/t/partition_error.test index 622b4f483b4..5b0c90b9a20 100644 --- a/mysql-test/suite/pbxt/t/partition_error.test +++ b/mysql-test/suite/pbxt/t/partition_error.test @@ -421,7 +421,7 @@ partitions 2 # # Partition by range, constant partition function not allowed # ---error ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR CREATE TABLE t1 ( a int not null, b int not null, @@ -636,7 +636,7 @@ partition by list (a); # # Partition by list, constant partition function not allowed # ---error ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR +--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR CREATE TABLE t1 ( a int not null, b int not null, diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 6292a93dd20..aa69bb47949 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -39,7 +39,8 @@ inline Item * and_items(Item* cond, Item *item) Item_subselect::Item_subselect(): Item_result_field(), value_assigned(0), thd(0), substitution(0), engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0), - const_item_cache(1), in_fix_fields(0), engine_changed(0), changed(0), is_correlated(FALSE) + const_item_cache(1), in_fix_fields(0), eliminated(FALSE), + engine_changed(0), changed(0), is_correlated(FALSE) { with_subselect= 1; reset(); @@ -431,6 +432,7 @@ void Item_maxmin_subselect::print(String *str, enum_query_type query_type) void Item_singlerow_subselect::reset() { + eliminated= FALSE; null_value= 1; if (value) value->null_value= 1; diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 50f8885f862..8d43f2bd383 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -90,6 +90,7 @@ public: void cleanup(); virtual void reset() { + eliminated= FALSE; null_value= 1; } virtual trans_res select_transformer(JOIN *join); @@ -235,6 +236,7 @@ public: subs_type substype() { return EXISTS_SUBS; } void reset() { + eliminated= FALSE; value= 0; } @@ -306,6 +308,7 @@ public: subs_type substype() { return IN_SUBS; } void reset() { + eliminated= FALSE; value= 0; null_value= 0; was_null= 0; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index c5c5191d176..143073a67b5 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -3019,8 +3019,9 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info, In case of PARTITION p VALUES LESS THAN MAXVALUE the maximum value is in the current partition. */ - if (part_func_value == part_end_val && - (loc_part_id < max_partition || !part_info->defined_max_value)) + if (part_func_value > part_end_val || + (part_func_value == part_end_val && + (loc_part_id < max_partition || !part_info->defined_max_value))) loc_part_id++; } else diff --git a/sql/table.cc b/sql/table.cc index 088a22b5203..d3fc85f2be8 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1847,8 +1847,8 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias, { if (work_part_info_used) tmp= fix_partition_func(thd, outparam, is_create_table); - outparam->part_info->item_free_list= part_func_arena.free_list; } + outparam->part_info->item_free_list= part_func_arena.free_list; partititon_err: if (tmp) {