diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result index f1fba87c70b..411cd52b4ca 100644 --- a/mysql-test/r/delete.result +++ b/mysql-test/r/delete.result @@ -163,3 +163,12 @@ select * from t1; a b 7 7 drop table t1; +CREATE TABLE t1 ( a int PRIMARY KEY ); +DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a; +INSERT INTO t1 VALUES (0),(1),(2); +DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a LIMIT 1; +SELECT * FROM t1; +a +0 +2 +DROP TABLE t1; diff --git a/mysql-test/r/drop_temp_table.result b/mysql-test/r/drop_temp_table.result index 163fc845e88..e3561ef9d07 100644 --- a/mysql-test/r/drop_temp_table.result +++ b/mysql-test/r/drop_temp_table.result @@ -17,8 +17,6 @@ master-bin.000001 # Query 1 # create database `drop-temp+table-test` master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table shortn1 (a int) master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table `table:name` (a int) master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table shortn2 (a int) -master-bin.000001 # Query 1 # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `drop-temp+table-test`.`shortn2` -master-bin.000001 # Query 1 # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `drop-temp+table-test`.`table:name` -master-bin.000001 # Query 1 # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `drop-temp+table-test`.`shortn1` +master-bin.000001 # Query 1 # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `drop-temp+table-test`.`shortn2`,`drop-temp+table-test`.`table:name`,`drop-temp+table-test`.`shortn1` master-bin.000001 # Query 1 # use `drop-temp+table-test`; DO RELEASE_LOCK("a") drop database `drop-temp+table-test`; diff --git a/mysql-test/r/rpl_drop_temp.result b/mysql-test/r/rpl_drop_temp.result new file mode 100644 index 00000000000..e00309cac8f --- /dev/null +++ b/mysql-test/r/rpl_drop_temp.result @@ -0,0 +1,12 @@ +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 database if not exists mysqltest; +create temporary table mysqltest.t1 (n int); +create temporary table mysqltest.t2 (n int); +show status like 'Slave_open_temp_tables'; +Variable_name Value +Slave_open_temp_tables 0 diff --git a/mysql-test/r/rpl_multi_query.result b/mysql-test/r/rpl_multi_query.result new file mode 100644 index 00000000000..2521dbe1ed9 --- /dev/null +++ b/mysql-test/r/rpl_multi_query.result @@ -0,0 +1,32 @@ +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 mysqltest; +create database mysqltest; +create table mysqltest.t1 ( n int); +insert into mysqltest.t1 values(1)/ +insert into mysqltest.t1 values(2); +insert into mysqltest.t1 values(3); +insert into mysqltest.t1 values(4); +insert into mysqltest.t1 values(5)/ +select * from mysqltest.t1; +n +1 +2 +3 +4 +5 +show binlog events from 79; +Log_name Pos Event_type Server_id Orig_log_pos Info +master-bin.000001 # Query 1 # drop database if exists mysqltest +master-bin.000001 # Query 1 # create database mysqltest +master-bin.000001 # Query 1 # use `test`; create table mysqltest.t1 ( n int) +master-bin.000001 # Query 1 # use `test`; insert into mysqltest.t1 values(1) +master-bin.000001 # Query 1 # use `test`; insert into mysqltest.t1 values(2) +master-bin.000001 # Query 1 # use `test`; insert into mysqltest.t1 values(3) +master-bin.000001 # Query 1 # use `test`; insert into mysqltest.t1 values(4) +master-bin.000001 # Query 1 # use `test`; insert into mysqltest.t1 values(5) +drop database mysqltest; diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test index 0bf7187865d..a6335d77a0c 100644 --- a/mysql-test/t/delete.test +++ b/mysql-test/t/delete.test @@ -141,3 +141,14 @@ delete t1 from t1 where a = 3; check table t1; select * from t1; drop table t1; + +# +# Bug #8392: delete with ORDER BY containing a direct reference to the table +# + +CREATE TABLE t1 ( a int PRIMARY KEY ); +DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a; +INSERT INTO t1 VALUES (0),(1),(2); +DELETE FROM t1 WHERE t1.a > 0 ORDER BY t1.a LIMIT 1; +SELECT * FROM t1; +DROP TABLE t1; diff --git a/mysql-test/t/rpl_drop_temp-slave.opt b/mysql-test/t/rpl_drop_temp-slave.opt new file mode 100644 index 00000000000..2f9244c65ff --- /dev/null +++ b/mysql-test/t/rpl_drop_temp-slave.opt @@ -0,0 +1,2 @@ +--replicate-ignore-table=mysqltest.t2 + diff --git a/mysql-test/t/rpl_drop_temp.test b/mysql-test/t/rpl_drop_temp.test new file mode 100644 index 00000000000..73d691d9d90 --- /dev/null +++ b/mysql-test/t/rpl_drop_temp.test @@ -0,0 +1,13 @@ +source include/master-slave.inc; +--disable_warnings +create database if not exists mysqltest; +--enable_warnings + +create temporary table mysqltest.t1 (n int); +create temporary table mysqltest.t2 (n int); +sync_slave_with_master; +connection master; +disconnect master; +connection slave; +--real_sleep 3; # time for DROP to be written +show status like 'Slave_open_temp_tables'; diff --git a/mysql-test/t/rpl_multi_query.test b/mysql-test/t/rpl_multi_query.test new file mode 100644 index 00000000000..482a2679e7a --- /dev/null +++ b/mysql-test/t/rpl_multi_query.test @@ -0,0 +1,29 @@ +# Test for BUG#8436: verify that a multi-query (i.e. one query +# containing several queries (assuming client has +# CLIENT_MULTI_STATEMENTS) will be binlogged ONE-query-per-event (not +# one binlog event containing all queries) + +# PS doesn't support multi-statements +--disable_ps_protocol + +source include/master-slave.inc; +--disable_warnings +drop database if exists mysqltest; +--enable_warnings +create database mysqltest; + +delimiter /; +create table mysqltest.t1 ( n int); +insert into mysqltest.t1 values(1)/ +insert into mysqltest.t1 values(2); +insert into mysqltest.t1 values(3); +insert into mysqltest.t1 values(4); +insert into mysqltest.t1 values(5)/ +delimiter ;/ +sync_slave_with_master; +select * from mysqltest.t1; +connection master; +--replace_column 2 # 5 # +show binlog events from 79; +drop database mysqltest; +sync_slave_with_master; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 15fbfcf928b..04cd542a387 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -135,6 +135,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, bzero((char*) &tables,sizeof(tables)); tables.table = table; + tables.alias = table_list->alias; table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), MYF(MY_FAE | MY_ZEROFILL)); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 03aa640a139..621f6de2461 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1671,6 +1671,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, { if (alloc_query(thd, packet, packet_length)) break; // fatal error is set + char *packet_end= thd->query + thd->query_length; mysql_log.write(thd,command,"%s",thd->query); DBUG_PRINT("query",("%-.4096s",thd->query)); mysql_parse(thd,thd->query, thd->query_length); @@ -1686,7 +1687,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, if (thd->lock || thd->open_tables || thd->derived_tables) close_thread_tables(thd); #endif - ulong length= thd->query_length-(ulong)(packet-thd->query); + ulong length= (ulong)(packet_end-packet); /* Remove garbage at start of query */ while (my_isspace(thd->charset(), *packet) && length > 0) @@ -2376,9 +2377,14 @@ mysql_execute_command(THD *thd) } /* Skip if we are in the slave thread, some table rules have been - given and the table list says the query should not be replicated + given and the table list says the query should not be replicated. + Exception is DROP TEMPORARY TABLE IF EXISTS: we always execute it + (otherwise we have stale files on slave caused by exclusion of one tmp + table). */ - if (all_tables_not_ok(thd, all_tables)) + if (!(lex->sql_command == SQLCOM_DROP_TABLE && + lex->drop_temporary && lex->drop_if_exists) && + all_tables_not_ok(thd, all_tables)) { /* we warn the slave SQL thread */ my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0)); @@ -4957,6 +4963,20 @@ void mysql_parse(THD *thd, char *inBuf, uint length) } else { + /* + Binlog logs a string starting from thd->query and having length + thd->query_length; so we set thd->query_length correctly (to not + log several statements in one event, when we executed only first). + We set it to not see the ';' (otherwise it would get into binlog + and Query_log_event::print() would give ';;' output). + This also helps display only the current query in SHOW + PROCESSLIST. + Note that we don't need LOCK_thread_count to modify query_length. + */ + if (lex->found_colon && + (thd->query_length= (ulong)(lex->found_colon - thd->query))) + thd->query_length--; + /* Actually execute the query */ mysql_execute_command(thd); query_cache_end_of_result(thd); }