List:Commits« Previous MessageNext Message »
From:He Zhenxing Date:December 9 2010 4:15am
Subject:bzr commit into mysql-5.1-bugteam branch (zhenxing.he:3418) Bug#42415
View as plain text  
#At file:///media/sdb2/hezx/work/mysql/bzr/b42415/5.1-bugteam/ based on revid:ramil@stripped

 3418 He Zhenxing	2010-12-09
      BUG#42415 UPDATE/DELETE with LIMIT clause unsafe for SBL even with ORDER BY PK clause
      
      UPDATE/DELETE/INSERT..SELECT with LIMIT clause were considered unsafe
      unconditionally, even if there is an ORDER BY PK or WHERE condition
      that can guarantee the result to be deterministic.
      
      The problem is fixed by implementing a algorithm to do more elaborate
      analyzed on the nature of the query to determine whether the query
      will cause uncertainty for replication or not.
      
      The statement will not be considered unsafe for following cases:
       - single table UPDATE/DELETE/INSERT..SELECT with ORDER BY
         <non null unique key>
       - single table UPDATE/DELETE/INSERT..SELECT with WHERE clause
         that include <non null unique key> = <const value>, if it is
         a multi-part key, then it must be <keypart1>=<const1> AND
         <keypart2>=<const2> ..., and this condition is ANDed with
         other conditions if there is any.
       - single table INSERT..SELECT with WHERE clause
         that include some parts of the non null unique key compare to
         const values, and the ORDER BY clause includes all the other
         key pars of the same non null unique key. for example (a,b) is
         a non null unique key, then WHERE a=<const> ORDER b will make
         the query result deterministic.
       - for INSERT..SELECT ... JOIN ..., the join condition (ON,
         USING, or WHERE) must include equations between columns of
         non null unique key of tables from both side of the join.
         For example t1 JOIN t2 USING (a,b), if (a,b) is not a non null
         unique key for both t1 and t2, then the result will be non-
         deterministic. otherwise the result can be deterministic with
         appropirate WHERE/ORDER clauses, and in this case, the same
         rule for single table above applys. But there is a difference
         for INNER JOIN with OUTER JOIN, for OUTER JOIN, only one table
         of the two JOIN tables will be used when checking the WHERE/ORDER
         conditions, it's the left table for LEFT JOIN and the right one
         for RIGHT JOIN when checking the keys. On the other hand, for
         INNER JOIN, keys from both tables can be used when checking
         the conditions. For example:
           INSERT..SELECT * FROM t1 INNER JOIN t2 USING(pk) ORDER BY nnuk LIMIT 1;
         This can be safe if nnuk is a non null unique key of either
         t1 or t2. But if we change the INNER JOIN to LEFT JOIN or
         RIGHT JOIN, then nnuk must be a non null unique key key of
         t1 (LEFT JOIN) or t2 (RIGHT JOIN) respectively.
       - If JOIN are nested, the will be handled recursively from inner
         outside.
       - UNIONs without global LIMIT are unsafe if any of sub-selects
         is unsafe, and safe if all sub-selects are safe. UNIONs with
         global LIMIT are marked unsafe no matter this is ORDER BY or
         not.
      
      If the key field length is longer than MAX_SORT_LENGTH, then it
      will be ignore and not treated as a key field.

    added:
      mysql-test/suite/binlog/r/binlog_unsafe_limit.result
      mysql-test/suite/binlog/t/binlog_unsafe_limit.test
    modified:
      mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result
      sql/sql_delete.cc
      sql/sql_insert.cc
      sql/sql_select.cc
      sql/sql_select.h
      sql/sql_update.cc
=== modified file 'mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result'
--- a/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result	2009-07-31 13:00:35 +0000
+++ b/mysql-test/suite/binlog/r/binlog_stm_unsafe_warning.result	2010-12-09 04:15:47 +0000
@@ -3,11 +3,7 @@ DROP TABLE IF EXISTS t1;
 CREATE TABLE t1 (a int, b int, primary key (a));
 INSERT INTO t1 VALUES (1,2), (2,3);
 UPDATE t1 SET b='4' WHERE a=1 LIMIT 1;
-Warnings:
-Note	1592	Statement may not be safe to log in statement format.
 UPDATE t1 SET b='5' WHERE a=2 ORDER BY a LIMIT 1;
-Warnings:
-Note	1592	Statement may not be safe to log in statement format.
 DROP TABLE t1;
 ### NOT filtered database => assertion: binlog disabled and warnings ARE NOT shown
 SET SQL_LOG_BIN= 0;

=== added file 'mysql-test/suite/binlog/r/binlog_unsafe_limit.result'
--- a/mysql-test/suite/binlog/r/binlog_unsafe_limit.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/binlog/r/binlog_unsafe_limit.result	2010-12-09 04:15:47 +0000
@@ -0,0 +1,1200 @@
+CREATE TABLE t (nokey INT, pk INT PRIMARY KEY, nnuk INT NOT NULL UNIQUE KEY, nuk INT UNIQUE KEY, nnuk1 INT NOT NULL, nnuk2 INT NOT NULL, UNIQUE KEY(nnuk1, nnuk2));
+CREATE TABLE t1 LIKE t;
+CREATE TABLE t2 LIKE t;
+CREATE TABLE t3 LIKE t;
+CREATE TABLE t4 LIKE t;
+CREATE TABLE queries (query VARCHAR(1024) NOT NULL);
+CREATE TABLE result_queries (id INT AUTO_INCREMENT PRIMARY KEY, query VARCHAR(1024) NOT NULL);
+CREATE TABLE limits (`limit` VARCHAR(256) NOT NULL);
+INSERT INTO queries(query) VALUES
+('UPDATE t SET nokey = nokey + 10 [LIMIT_1]'),
+('UPDATE t SET nokey = nokey + 10 WHERE nokey=1 [LIMIT_1]'),
+('UPDATE t SET nokey = nokey + 10 WHERE nuk=1   [LIMIT_1]'),
+('UPDATE t SET nokey = nokey + 10 WHERE nnuk=1  [LIMIT_1]'),
+('UPDATE t SET nokey = nokey + 10 WHERE pk=1    [LIMIT_1]'),
+('DELETE FROM t [LIMIT_1]'),
+('DELETE FROM t WHERE nokey=1 [LIMIT_1]'),
+('DELETE FROM t WHERE nuk=1   [LIMIT_1]'),
+('DELETE FROM t WHERE nnuk=1  [LIMIT_1]'),
+('DELETE FROM t WHERE pk=1    [LIMIT_1]'),
+('REPLACE INTO t SELECT * FROM t1 [LIMIT_1]'),
+('REPLACE INTO t SELECT * FROM t1 WHERE nokey=1 [LIMIT_1]'),
+('REPLACE INTO t SELECT * FROM t1 WHERE nuk=1   [LIMIT_1]'),
+('REPLACE INTO t SELECT * FROM t1 WHERE nnuk=1  [LIMIT_1]'),
+('REPLACE INTO t SELECT * FROM t1 WHERE pk=1    [LIMIT_1]'),
+('INSERT INTO t SELECT * FROM t1 [LIMIT_1]'),
+('INSERT INTO t SELECT * FROM t1 WHERE nokey=1 [LIMIT_1]'),
+('INSERT INTO t SELECT * FROM t1 WHERE nuk=1   [LIMIT_1]'),
+('INSERT INTO t SELECT * FROM t1 WHERE nnuk=1  [LIMIT_1]'),
+('INSERT INTO t SELECT * FROM t1 WHERE pk=1    [LIMIT_1]'),
+('INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2) [LIMIT_1]'),
+('INSERT INTO t (SELECT * FROM t1 [LIMIT_1]) UNION (SELECT * FROM t2)'),
+('INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2 [LIMIT_1])'),
+('INSERT INTO t (SELECT * FROM t1 [LIMIT_1]) UNION (SELECT * FROM t2 [LIMIT_2])'),
+('INSERT INTO t SELECT * FROM (SELECT * FROM t1 [LIMIT_1]) AS subselect [LIMIT_2]'),
+('INSERT INTO t SELECT t1.* FROM t1, t2 [LIMIT_1]'),
+('INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nokey=t2.nokey [LIMIT_1]'),
+('INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nuk=t2.nuk     [LIMIT_1]'),
+('INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nnuk=t2.nnuk   [LIMIT_1]'),
+('INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.pk=t2.pk       [LIMIT_1]'),
+('INSERT INTO t SELECT t1.* FROM t1 NATURAL JOIN t2 [LIMIT_1]'),
+('INSERT INTO t SELECT t1.* FROM t1 JOIN t2 USING(pk) [LIMIT_1]'),
+('INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk1 AND t1.nnuk2=t2.nnuk2 [LIMIT_1]'),
+('INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk2 AND t1.nnuk2=t2.nnuk1 [LIMIT_1]'),
+('INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN t3 USING (pk)) USING(pk) [LIMIT_1]'),
+('INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.pk=t3.pk) ON t1.pk=t4.pk [LIMIT_1]'),
+('INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 [LIMIT_1]'),
+('INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 AND t2.pk=1 [LIMIT_1]'),
+('INSERT INTO t SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.pk=t2.pk [LIMIT_1]'),
+('INSERT INTO t SELECT t2.* FROM t1 RIGHT JOIN t2 ON t1.pk=t2.pk [LIMIT_1]');
+INSERT INTO limits (`limit`) VALUES
+('LIMIT 0'),
+('LIMIT 1'),
+('ORDER BY nokey LIMIT 1'),
+('ORDER BY nuk LIMIT 1'),
+('ORDER BY nnuk1 LIMIT 1'),
+('ORDER BY nnuk LIMIT 1'),
+('ORDER BY pk LIMIT 1'),
+('ORDER BY nnuk1, nnuk2 LIMIT 1'),
+('ORDER BY nnuk1, nnuk2, nokey LIMIT 1'),
+('ORDER BY nnuk1, nokey, nnuk2 LIMIT 1');
+CREATE PROCEDURE gen_queries()
+BEGIN
+DECLARE done INT DEFAULT 0;
+DECLARE q VARCHAR(1024);
+DECLARE limit1, limit2 VARCHAR(256);
+DECLARE qcur CURSOR FOR SELECT * FROM queries;
+DECLARE lcur1 CURSOR FOR SELECT * FROM limits;
+DECLARE lcur2 CURSOR FOR SELECT * FROM limits;
+DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
+OPEN qcur;
+FETCH qcur INTO q;
+WHILE done <> 1 DO
+OPEN lcur1;
+FETCH lcur1 INTO limit1;
+WHILE done <> 1 DO
+IF LOCATE('[LIMIT_2]', q) > 0 THEN
+OPEN lcur2;
+FETCH lcur2 INTO limit2;
+WHILE done <> 1 DO
+SELECT REPLACE(REPLACE(q, '[LIMIT_1]', limit1), '[LIMIT_2]', limit2) INTO @query;
+FETCH lcur2 INTO limit2;
+END WHILE;
+CLOSE lcur2;
+SET done = 0;
+ELSE
+SELECT REPLACE(q, '[LIMIT_1]', limit1) INTO @query;
+END IF;
+INSERT INTO result_queries set query=@query;
+FETCH lcur1 INTO limit1;
+END WHILE;
+CLOSE lcur1;
+SET done = 0;
+FETCH qcur INTO q;
+END WHILE;
+CLOSE qcur;
+END|
+call gen_queries();
+UPDATE t SET nokey = nokey + 10 LIMIT 0;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nokey=1 LIMIT 0;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nokey=1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nokey=1 ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nokey=1 ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nokey=1 ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nokey=1 ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nokey=1 ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nokey=1 ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nokey=1 ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nokey=1 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nuk=1   LIMIT 0;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nuk=1   LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nuk=1   ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nuk=1   ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nuk=1   ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nuk=1   ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nuk=1   ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nuk=1   ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nuk=1   ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nuk=1   ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nnuk=1  LIMIT 0;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nnuk=1  LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nnuk=1  ORDER BY nokey LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nnuk=1  ORDER BY nuk LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nnuk=1  ORDER BY nnuk1 LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nnuk=1  ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nnuk=1  ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nnuk=1  ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nnuk=1  ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE nnuk=1  ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE pk=1    LIMIT 0;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE pk=1    LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE pk=1    ORDER BY nokey LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE pk=1    ORDER BY nuk LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE pk=1    ORDER BY nnuk1 LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE pk=1    ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE pk=1    ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE pk=1    ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE pk=1    ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+UPDATE t SET nokey = nokey + 10 WHERE pk=1    ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+DELETE FROM t LIMIT 0;
+ROWS in table t: 2
+DELETE FROM t LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 1
+DELETE FROM t ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 1
+DELETE FROM t ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 1
+DELETE FROM t ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 1
+DELETE FROM t ORDER BY nnuk LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t ORDER BY pk LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nokey=1 LIMIT 0;
+ROWS in table t: 2
+DELETE FROM t WHERE nokey=1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 1
+DELETE FROM t WHERE nokey=1 ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 1
+DELETE FROM t WHERE nokey=1 ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 1
+DELETE FROM t WHERE nokey=1 ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 1
+DELETE FROM t WHERE nokey=1 ORDER BY nnuk LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nokey=1 ORDER BY pk LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nokey=1 ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nokey=1 ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nokey=1 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nuk=1   LIMIT 0;
+ROWS in table t: 2
+DELETE FROM t WHERE nuk=1   LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 1
+DELETE FROM t WHERE nuk=1   ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 1
+DELETE FROM t WHERE nuk=1   ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 1
+DELETE FROM t WHERE nuk=1   ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 1
+DELETE FROM t WHERE nuk=1   ORDER BY nnuk LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nuk=1   ORDER BY pk LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nuk=1   ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nuk=1   ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nuk=1   ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nnuk=1  LIMIT 0;
+ROWS in table t: 2
+DELETE FROM t WHERE nnuk=1  LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nnuk=1  ORDER BY nokey LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nnuk=1  ORDER BY nuk LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nnuk=1  ORDER BY nnuk1 LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nnuk=1  ORDER BY nnuk LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nnuk=1  ORDER BY pk LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nnuk=1  ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nnuk=1  ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE nnuk=1  ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE pk=1    LIMIT 0;
+ROWS in table t: 2
+DELETE FROM t WHERE pk=1    LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE pk=1    ORDER BY nokey LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE pk=1    ORDER BY nuk LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE pk=1    ORDER BY nnuk1 LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE pk=1    ORDER BY nnuk LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE pk=1    ORDER BY pk LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE pk=1    ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE pk=1    ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 1
+DELETE FROM t WHERE pk=1    ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 1
+REPLACE INTO t SELECT * FROM t1 LIMIT 0;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+REPLACE INTO t SELECT * FROM t1 ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+REPLACE INTO t SELECT * FROM t1 ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+REPLACE INTO t SELECT * FROM t1 ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+REPLACE INTO t SELECT * FROM t1 ORDER BY nnuk LIMIT 1;
+ROWS in table t: 3
+REPLACE INTO t SELECT * FROM t1 ORDER BY pk LIMIT 1;
+ROWS in table t: 3
+REPLACE INTO t SELECT * FROM t1 ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 3
+REPLACE INTO t SELECT * FROM t1 ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 3
+REPLACE INTO t SELECT * FROM t1 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 3
+REPLACE INTO t SELECT * FROM t1 WHERE nokey=1 LIMIT 0;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nokey=1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nokey=1 ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nokey=1 ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nokey=1 ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nokey=1 ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nokey=1 ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nokey=1 ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nokey=1 ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nokey=1 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nuk=1   LIMIT 0;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nuk=1   LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nuk=1   ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nuk=1   ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nuk=1   ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nuk=1   ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nuk=1   ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nuk=1   ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nuk=1   ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nuk=1   ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nnuk=1  LIMIT 0;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nnuk=1  LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nnuk=1  ORDER BY nokey LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nnuk=1  ORDER BY nuk LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nnuk=1  ORDER BY nnuk1 LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nnuk=1  ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nnuk=1  ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nnuk=1  ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nnuk=1  ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE nnuk=1  ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE pk=1    LIMIT 0;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE pk=1    LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE pk=1    ORDER BY nokey LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE pk=1    ORDER BY nuk LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE pk=1    ORDER BY nnuk1 LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE pk=1    ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE pk=1    ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE pk=1    ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE pk=1    ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+REPLACE INTO t SELECT * FROM t1 WHERE pk=1    ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM t1 ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM t1 ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM t1 ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM t1 ORDER BY nnuk LIMIT 1;
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM t1 ORDER BY pk LIMIT 1;
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM t1 ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM t1 ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM t1 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM t1 WHERE nokey=1 LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nokey=1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nokey=1 ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nokey=1 ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nokey=1 ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nokey=1 ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nokey=1 ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nokey=1 ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nokey=1 ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nokey=1 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nuk=1   LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nuk=1   LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nuk=1   ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nuk=1   ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nuk=1   ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nuk=1   ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nuk=1   ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nuk=1   ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nuk=1   ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nuk=1   ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nnuk=1  LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nnuk=1  LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nnuk=1  ORDER BY nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nnuk=1  ORDER BY nuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nnuk=1  ORDER BY nnuk1 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nnuk=1  ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nnuk=1  ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nnuk=1  ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nnuk=1  ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE nnuk=1  ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE pk=1    LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE pk=1    LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE pk=1    ORDER BY nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE pk=1    ORDER BY nuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE pk=1    ORDER BY nnuk1 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE pk=1    ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE pk=1    ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE pk=1    ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE pk=1    ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM t1 WHERE pk=1    ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2) LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2) LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2) ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2) ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2) ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2) ORDER BY nnuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2) ORDER BY pk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2) ORDER BY nnuk1, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2) ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2) ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t (SELECT * FROM t1 LIMIT 0) UNION (SELECT * FROM t2);
+ROWS in table t: 4
+INSERT INTO t (SELECT * FROM t1 LIMIT 1) UNION (SELECT * FROM t2);
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1 ORDER BY nokey LIMIT 1) UNION (SELECT * FROM t2);
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1 ORDER BY nuk LIMIT 1) UNION (SELECT * FROM t2);
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1 ORDER BY nnuk1 LIMIT 1) UNION (SELECT * FROM t2);
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1 ORDER BY nnuk LIMIT 1) UNION (SELECT * FROM t2);
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1 ORDER BY pk LIMIT 1) UNION (SELECT * FROM t2);
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1 ORDER BY nnuk1, nnuk2 LIMIT 1) UNION (SELECT * FROM t2);
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1 ORDER BY nnuk1, nnuk2, nokey LIMIT 1) UNION (SELECT * FROM t2);
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1) UNION (SELECT * FROM t2);
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2 LIMIT 0);
+ROWS in table t: 4
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2 LIMIT 1);
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2 ORDER BY nokey LIMIT 1);
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2 ORDER BY nuk LIMIT 1);
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2 ORDER BY nnuk1 LIMIT 1);
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2 ORDER BY nnuk LIMIT 1);
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2 ORDER BY pk LIMIT 1);
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2 ORDER BY nnuk1, nnuk2 LIMIT 1);
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2 ORDER BY nnuk1, nnuk2, nokey LIMIT 1);
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1);
+ROWS in table t: 5
+INSERT INTO t (SELECT * FROM t1 LIMIT 0) UNION (SELECT * FROM t2 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1);
+ROWS in table t: 3
+INSERT INTO t (SELECT * FROM t1 LIMIT 1) UNION (SELECT * FROM t2 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1);
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 4
+INSERT INTO t (SELECT * FROM t1 ORDER BY nokey LIMIT 1) UNION (SELECT * FROM t2 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1);
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 4
+INSERT INTO t (SELECT * FROM t1 ORDER BY nuk LIMIT 1) UNION (SELECT * FROM t2 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1);
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 4
+INSERT INTO t (SELECT * FROM t1 ORDER BY nnuk1 LIMIT 1) UNION (SELECT * FROM t2 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1);
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 4
+INSERT INTO t (SELECT * FROM t1 ORDER BY nnuk LIMIT 1) UNION (SELECT * FROM t2 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1);
+ROWS in table t: 4
+INSERT INTO t (SELECT * FROM t1 ORDER BY pk LIMIT 1) UNION (SELECT * FROM t2 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1);
+ROWS in table t: 4
+INSERT INTO t (SELECT * FROM t1 ORDER BY nnuk1, nnuk2 LIMIT 1) UNION (SELECT * FROM t2 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1);
+ROWS in table t: 4
+INSERT INTO t (SELECT * FROM t1 ORDER BY nnuk1, nnuk2, nokey LIMIT 1) UNION (SELECT * FROM t2 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1);
+ROWS in table t: 4
+INSERT INTO t (SELECT * FROM t1 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1) UNION (SELECT * FROM t2 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1);
+ROWS in table t: 4
+INSERT INTO t SELECT * FROM (SELECT * FROM t1 LIMIT 0) AS subselect ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT * FROM (SELECT * FROM t1 LIMIT 1) AS subselect ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM (SELECT * FROM t1 ORDER BY nokey LIMIT 1) AS subselect ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM (SELECT * FROM t1 ORDER BY nuk LIMIT 1) AS subselect ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM (SELECT * FROM t1 ORDER BY nnuk1 LIMIT 1) AS subselect ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM (SELECT * FROM t1 ORDER BY nnuk LIMIT 1) AS subselect ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM (SELECT * FROM t1 ORDER BY pk LIMIT 1) AS subselect ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM (SELECT * FROM t1 ORDER BY nnuk1, nnuk2 LIMIT 1) AS subselect ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM (SELECT * FROM t1 ORDER BY nnuk1, nnuk2, nokey LIMIT 1) AS subselect ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT * FROM (SELECT * FROM t1 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1) AS subselect ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1, t2 LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1, t2 ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1, t2 ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1, t2 ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1, t2 ORDER BY nnuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1, t2 ORDER BY pk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1, t2 ORDER BY nnuk1, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1, t2 ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1, t2 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nokey=t2.nokey LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nokey=t2.nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nokey=t2.nokey ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nokey=t2.nokey ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nokey=t2.nokey ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nokey=t2.nokey ORDER BY nnuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nokey=t2.nokey ORDER BY pk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nokey=t2.nokey ORDER BY nnuk1, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nokey=t2.nokey ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nokey=t2.nokey ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nuk=t2.nuk     LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nuk=t2.nuk     LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nuk=t2.nuk     ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nuk=t2.nuk     ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nuk=t2.nuk     ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nuk=t2.nuk     ORDER BY nnuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nuk=t2.nuk     ORDER BY pk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nuk=t2.nuk     ORDER BY nnuk1, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nuk=t2.nuk     ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nuk=t2.nuk     ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nnuk=t2.nnuk   LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nnuk=t2.nnuk   LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nnuk=t2.nnuk   ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nnuk=t2.nnuk   ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nnuk=t2.nnuk   ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nnuk=t2.nnuk   ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nnuk=t2.nnuk   ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nnuk=t2.nnuk   ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nnuk=t2.nnuk   ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nnuk=t2.nnuk   ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.pk=t2.pk       LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.pk=t2.pk       LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.pk=t2.pk       ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.pk=t2.pk       ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.pk=t2.pk       ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.pk=t2.pk       ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.pk=t2.pk       ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.pk=t2.pk       ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.pk=t2.pk       ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.pk=t2.pk       ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 NATURAL JOIN t2 LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 NATURAL JOIN t2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 NATURAL JOIN t2 ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 NATURAL JOIN t2 ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 NATURAL JOIN t2 ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 NATURAL JOIN t2 ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 NATURAL JOIN t2 ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 NATURAL JOIN t2 ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 NATURAL JOIN t2 ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 NATURAL JOIN t2 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 USING(pk) LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 USING(pk) LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 USING(pk) ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 USING(pk) ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 USING(pk) ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 USING(pk) ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 USING(pk) ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 USING(pk) ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 USING(pk) ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 USING(pk) ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk1 AND t1.nnuk2=t2.nnuk2 LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk1 AND t1.nnuk2=t2.nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk1 AND t1.nnuk2=t2.nnuk2 ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk1 AND t1.nnuk2=t2.nnuk2 ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk1 AND t1.nnuk2=t2.nnuk2 ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk1 AND t1.nnuk2=t2.nnuk2 ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk1 AND t1.nnuk2=t2.nnuk2 ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk1 AND t1.nnuk2=t2.nnuk2 ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk1 AND t1.nnuk2=t2.nnuk2 ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk1 AND t1.nnuk2=t2.nnuk2 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk2 AND t1.nnuk2=t2.nnuk1 LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk2 AND t1.nnuk2=t2.nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk2 AND t1.nnuk2=t2.nnuk1 ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk2 AND t1.nnuk2=t2.nnuk1 ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk2 AND t1.nnuk2=t2.nnuk1 ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk2 AND t1.nnuk2=t2.nnuk1 ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk2 AND t1.nnuk2=t2.nnuk1 ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk2 AND t1.nnuk2=t2.nnuk1 ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk2 AND t1.nnuk2=t2.nnuk1 ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk2 AND t1.nnuk2=t2.nnuk1 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN t3 USING (pk)) USING(pk) LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN t3 USING (pk)) USING(pk) LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN t3 USING (pk)) USING(pk) ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN t3 USING (pk)) USING(pk) ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN t3 USING (pk)) USING(pk) ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN t3 USING (pk)) USING(pk) ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN t3 USING (pk)) USING(pk) ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN t3 USING (pk)) USING(pk) ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN t3 USING (pk)) USING(pk) ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN t3 USING (pk)) USING(pk) ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.pk=t3.pk) ON t1.pk=t4.pk LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.pk=t3.pk) ON t1.pk=t4.pk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.pk=t3.pk) ON t1.pk=t4.pk ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.pk=t3.pk) ON t1.pk=t4.pk ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.pk=t3.pk) ON t1.pk=t4.pk ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.pk=t3.pk) ON t1.pk=t4.pk ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.pk=t3.pk) ON t1.pk=t4.pk ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.pk=t3.pk) ON t1.pk=t4.pk ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.pk=t3.pk) ON t1.pk=t4.pk ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.pk=t3.pk) ON t1.pk=t4.pk ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 AND t2.pk=1 LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 AND t2.pk=1 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 AND t2.pk=1 ORDER BY nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 AND t2.pk=1 ORDER BY nuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 AND t2.pk=1 ORDER BY nnuk1 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 AND t2.pk=1 ORDER BY nnuk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 AND t2.pk=1 ORDER BY pk LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 AND t2.pk=1 ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 AND t2.pk=1 ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 AND t2.pk=1 ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.pk=t2.pk LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.pk=t2.pk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.pk=t2.pk ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.pk=t2.pk ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.pk=t2.pk ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.pk=t2.pk ORDER BY nnuk LIMIT 1;
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.pk=t2.pk ORDER BY pk LIMIT 1;
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.pk=t2.pk ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.pk=t2.pk ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 3
+INSERT INTO t SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.pk=t2.pk ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 3
+INSERT INTO t SELECT t2.* FROM t1 RIGHT JOIN t2 ON t1.pk=t2.pk LIMIT 0;
+ROWS in table t: 2
+INSERT INTO t SELECT t2.* FROM t1 RIGHT JOIN t2 ON t1.pk=t2.pk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t2.* FROM t1 RIGHT JOIN t2 ON t1.pk=t2.pk ORDER BY nokey LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t2.* FROM t1 RIGHT JOIN t2 ON t1.pk=t2.pk ORDER BY nuk LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t2.* FROM t1 RIGHT JOIN t2 ON t1.pk=t2.pk ORDER BY nnuk1 LIMIT 1;
+Warnings:
+Note	1592	Statement may not be safe to log in statement format.
+ROWS in table t: 3
+INSERT INTO t SELECT t2.* FROM t1 RIGHT JOIN t2 ON t1.pk=t2.pk ORDER BY nnuk LIMIT 1;
+ROWS in table t: 3
+INSERT INTO t SELECT t2.* FROM t1 RIGHT JOIN t2 ON t1.pk=t2.pk ORDER BY pk LIMIT 1;
+ROWS in table t: 3
+INSERT INTO t SELECT t2.* FROM t1 RIGHT JOIN t2 ON t1.pk=t2.pk ORDER BY nnuk1, nnuk2 LIMIT 1;
+ROWS in table t: 3
+INSERT INTO t SELECT t2.* FROM t1 RIGHT JOIN t2 ON t1.pk=t2.pk ORDER BY nnuk1, nnuk2, nokey LIMIT 1;
+ROWS in table t: 3
+INSERT INTO t SELECT t2.* FROM t1 RIGHT JOIN t2 ON t1.pk=t2.pk ORDER BY nnuk1, nokey, nnuk2 LIMIT 1;
+ROWS in table t: 3
+DROP TABLE t, t1, t2, t3, t4;
+DROP TABLE queries, result_queries, limits;
+DROP PROCEDURE gen_queries;

=== added file 'mysql-test/suite/binlog/t/binlog_unsafe_limit.test'
--- a/mysql-test/suite/binlog/t/binlog_unsafe_limit.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/binlog/t/binlog_unsafe_limit.test	2010-12-09 04:15:47 +0000
@@ -0,0 +1,221 @@
+# ==== Purpose ====
+#
+# Test under what circumstances there is a warning for unsafe
+# statements on the following form:
+#
+# [INSERT...SELECT | REPLACE...SELECT | DELETE | UPDATE] ... ORDER BY ... LIMIT
+#
+# INSERT...SELECT...LIMIT should give a warning because the order of
+# rows may differ between master and slave, so the LIMIT may select a
+# different set of rows on master and slave.  However, if there is an
+# 'ORDER BY primary_key', then the order is known and there should not
+# be any warning.  The same is true for REPLACE...SELECT, DELETE, and
+# UPDATE.  In REPLACE...SELECT and INSERT...SELECT, the select may be
+# compound using UNION or JOIN or subqueries in the FROM clause.  So
+# we test LIMIT in various places in the subqueries.
+#
+# We also test various forms of ORDER BY ... LIMIT. If there is one
+# ORDER BY column and it is a PRIMARY KEY or NOT NULL UNIQUE KEY, then
+# the order is deterministic.  If there is one ORDER BY column and it
+# is neither a PRIMARY KEY nor a NOT NULL UNIQUE KEY, then the order
+# is not deterministic.  If the ORDER BY consists of several columns,
+# and a prefix of the ORDER BY columns is a PRIMARY KEY or NOT NULL
+# UNIQUE KEY, then the order is deterministic.  If the ORDER BY
+# consists of several columns, and no prefix of the ORDER BY COLUMNS
+# is a PRIMARY KEY or NOT NULL UNIQUE KEY, then the order is not
+# deterministic.
+
+source include/have_log_bin.inc;
+source include/have_binlog_format_statement.inc;
+
+#
+# Create the tables for test
+# Where:
+#    - nokey is a column not part of key
+#    - pk is column of the primary key
+#    - nuk is a column of UNIQUE KEY, which can be NULL.
+#    - nnuk is a column of NOT NULL UNIQUE KEY
+#    - nnuk1 and nnuk2 are NOT NULL columns, and togather forms a UNIQUE KEY.
+#
+#CREATE TABLE t (nokey INT, pk INT PRIMARY KEY, nnuk INT NOT NULL UNIQUE KEY, nuk INT UNIQUE KEY, nnuk1 INT NOT NULL, nnuk2 INT NOT NULL, UNIQUE KEY(nnuk1, nnuk2));
+CREATE TABLE t (nokey INT, pk INT PRIMARY KEY, nnuk INT NOT NULL UNIQUE KEY, nuk INT UNIQUE KEY,
+                nnuk1 INT NOT NULL, nnuk2 INT NOT NULL, UNIQUE KEY(nnuk1, nnuk2),
+		nnuk_str_long VARCHAR(512) NOT NULL UNIQUE KEY,
+		nnuk_str_short VARCHAR(50) NOT NULL UNIQUE KEY);
+CREATE TABLE t1 LIKE t;
+CREATE TABLE t2 LIKE t;
+CREATE TABLE t3 LIKE t;
+CREATE TABLE t4 LIKE t;
+
+
+CREATE TABLE queries (query VARCHAR(1024) NOT NULL);
+CREATE TABLE result_queries (id INT AUTO_INCREMENT PRIMARY KEY, query VARCHAR(1024) NOT NULL);
+CREATE TABLE limits (`limit` VARCHAR(256) NOT NULL);
+
+#
+# Iterate through the following queries
+#
+# [LIMIT_1] and [LIMIT_2] will iterate over the strings in table `limits`
+#
+INSERT INTO queries(query) VALUES
+	('UPDATE t SET nokey = nokey + 10 [LIMIT_1]'),
+	('UPDATE t SET nokey = nokey + 10 WHERE nokey=1 [LIMIT_1]'),
+	('UPDATE t SET nokey = nokey + 10 WHERE nuk=1   [LIMIT_1]'),
+	('UPDATE t SET nokey = nokey + 10 WHERE nnuk=1  [LIMIT_1]'),
+	('UPDATE t SET nokey = nokey + 10 WHERE pk=1    [LIMIT_1]'),
+
+	('DELETE FROM t [LIMIT_1]'),
+	('DELETE FROM t WHERE nokey=1 [LIMIT_1]'),
+	('DELETE FROM t WHERE nuk=1   [LIMIT_1]'),
+	('DELETE FROM t WHERE nnuk=1  [LIMIT_1]'),
+	('DELETE FROM t WHERE pk=1    [LIMIT_1]'),
+
+	('REPLACE INTO t SELECT * FROM t1 [LIMIT_1]'),
+	('REPLACE INTO t SELECT * FROM t1 WHERE nokey=1 [LIMIT_1]'),
+	('REPLACE INTO t SELECT * FROM t1 WHERE nuk=1   [LIMIT_1]'),
+	('REPLACE INTO t SELECT * FROM t1 WHERE nnuk=1  [LIMIT_1]'),
+	('REPLACE INTO t SELECT * FROM t1 WHERE pk=1    [LIMIT_1]'),
+					 
+	('INSERT INTO t SELECT * FROM t1 [LIMIT_1]'),
+	('INSERT INTO t SELECT * FROM t1 WHERE nokey=1 [LIMIT_1]'),
+	('INSERT INTO t SELECT * FROM t1 WHERE nuk=1   [LIMIT_1]'),
+	('INSERT INTO t SELECT * FROM t1 WHERE nnuk=1  [LIMIT_1]'),
+	('INSERT INTO t SELECT * FROM t1 WHERE pk=1    [LIMIT_1]'),
+
+	('INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2) [LIMIT_1]'),
+	('INSERT INTO t (SELECT * FROM t1 [LIMIT_1]) UNION (SELECT * FROM t2)'),
+	('INSERT INTO t (SELECT * FROM t1) UNION (SELECT * FROM t2 [LIMIT_1])'),
+	('INSERT INTO t (SELECT * FROM t1 [LIMIT_1]) UNION (SELECT * FROM t2 [LIMIT_2])'),
+
+	('INSERT INTO t SELECT * FROM (SELECT * FROM t1 [LIMIT_1]) AS subselect [LIMIT_2]'),
+	('INSERT INTO t SELECT t1.* FROM t1, t2 [LIMIT_1]'),
+	('INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nokey=t2.nokey [LIMIT_1]'),
+	('INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nuk=t2.nuk     [LIMIT_1]'),
+	('INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.nnuk=t2.nnuk   [LIMIT_1]'),
+	('INSERT INTO t SELECT t1.* FROM t1, t2 WHERE t1.pk=t2.pk       [LIMIT_1]'),
+
+	('INSERT INTO t SELECT t1.* FROM t1 NATURAL JOIN t2 [LIMIT_1]'),
+	('INSERT INTO t SELECT t1.* FROM t1 JOIN t2 USING(pk) [LIMIT_1]'),
+	('INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk1 AND t1.nnuk2=t2.nnuk2 [LIMIT_1]'),
+	('INSERT INTO t SELECT t1.* FROM t1 JOIN t2 ON t1.nnuk1=t2.nnuk2 AND t1.nnuk2=t2.nnuk1 [LIMIT_1]'),
+	('INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN t3 USING (pk)) USING(pk) [LIMIT_1]'),
+	('INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.pk=t3.pk) ON t1.pk=t4.pk [LIMIT_1]'),
+	('INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 [LIMIT_1]'),
+	('INSERT INTO t SELECT t1.* FROM t1 JOIN (t2 JOIN (t3 JOIN t4 USING (pk)) ON t2.nnuk=t3.nnuk) ON t1.nnuk1=t4.nnuk1 AND t1.nnuk2=t4.nnuk2 AND t2.pk=1 [LIMIT_1]'),
+	('INSERT INTO t SELECT t1.* FROM t1 LEFT JOIN t2 ON t1.pk=t2.pk [LIMIT_1]'),
+	('INSERT INTO t SELECT t2.* FROM t1 RIGHT JOIN t2 ON t1.pk=t2.pk [LIMIT_1]');
+
+
+#
+# Let the LIMIT cluase ([LIMIT_1] and [LIMIT_2]) iterate through the following strings:
+#
+INSERT INTO limits (`limit`) VALUES
+	('LIMIT 0'),
+	('LIMIT 1'),
+	('ORDER BY nokey LIMIT 1'),
+	('ORDER BY nuk LIMIT 1'),
+	('ORDER BY nnuk1 LIMIT 1'),
+	('ORDER BY nnuk LIMIT 1'),
+	('ORDER BY nnuk_str_short LIMIT 1'),
+	('ORDER BY nnuk_str_long LIMIT 1'),
+	('ORDER BY pk LIMIT 1'),
+	('ORDER BY nnuk1, nnuk2 LIMIT 1'),
+	('ORDER BY nnuk1, nnuk2, nokey LIMIT 1'),
+	('ORDER BY nnuk1, nokey, nnuk2 LIMIT 1');
+
+
+DELIMITER |;
+
+#
+# This function is used to generate the queries by replace [LIMIT_1]
+# and [LIMIT_2] with values in table `limits` for values in table
+# `queries`. And the result will be save in table `result_queries`.
+#
+
+CREATE PROCEDURE gen_queries()
+BEGIN
+  DECLARE done INT DEFAULT 0;
+  DECLARE q VARCHAR(1024);
+  DECLARE limit1, limit2 VARCHAR(256);
+  DECLARE qcur CURSOR FOR SELECT * FROM queries;
+  DECLARE lcur1 CURSOR FOR SELECT * FROM limits;
+  DECLARE lcur2 CURSOR FOR SELECT * FROM limits;
+  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done=1;
+
+  OPEN qcur;
+
+  FETCH qcur INTO q;
+  WHILE done <> 1 DO
+    OPEN lcur1;
+    FETCH lcur1 INTO limit1;
+    WHILE done <> 1 DO
+
+      IF LOCATE('[LIMIT_2]', q) > 0 THEN
+        OPEN lcur2;
+	FETCH lcur2 INTO limit2;
+        WHILE done <> 1 DO
+	  SELECT REPLACE(REPLACE(q, '[LIMIT_1]', limit1), '[LIMIT_2]', limit2) INTO @query;
+	  FETCH lcur2 INTO limit2;
+	END WHILE;
+	CLOSE lcur2;
+	SET done = 0;
+      ELSE
+        SELECT REPLACE(q, '[LIMIT_1]', limit1) INTO @query;
+      END IF;
+      INSERT INTO result_queries set query=@query;
+      FETCH lcur1 INTO limit1;
+    END WHILE;
+    CLOSE lcur1;
+    SET done = 0;
+    FETCH qcur INTO q;
+  END WHILE;
+  CLOSE qcur;
+END|
+
+DELIMITER ;|
+
+call gen_queries();
+
+#
+# Execute the generated queries
+#
+let $count= `SELECT COUNT(*) FROM result_queries`;
+let $id=1;
+SET MAX_SORT_LENGTH=50;
+while (`SELECT $id <= $count`)
+{
+  disable_query_log;
+  TRUNCATE t;
+  TRUNCATE t1;
+  TRUNCATE t2;
+  TRUNCATE t3;
+  TRUNCATE t4;
+
+  # INSERT INTO t VALUES  (1, 1, 1, 1, 1, 1), (2, 2, 2, 2, 2, 2);
+  # INSERT INTO t1 VALUES (3, 3, 3, 3, 3, 3), (4, 4, 4, 4, 4, 4);
+  # INSERT INTO t2 VALUES (5, 5, 5, 5, 5, 5), (6, 6, 6, 6, 6, 6);
+  # INSERT INTO t3 VALUES (7, 7, 7, 7, 7, 7), (8, 8, 8, 8, 8, 8);
+  # INSERT INTO t4 VALUES (9, 9, 9, 9, 9, 9), (10, 10, 10, 10, 10, 10);
+
+  INSERT INTO t VALUES  (1, 1, 1, 1, 1, 1, "a", "a"), (2, 2, 2, 2, 2, 2, "b", "b");
+  INSERT INTO t1 VALUES (3, 3, 3, 3, 3, 3, "c", "c"), (4, 4, 4, 4, 4, 4, "d", "d");
+  INSERT INTO t2 VALUES (5, 5, 5, 5, 5, 5, "e", "e"), (6, 6, 6, 6, 6, 6, "f", "f");
+  INSERT INTO t3 VALUES (7, 7, 7, 7, 7, 7, "g", "g"), (8, 8, 8, 8, 8, 8, "h", "h");
+  INSERT INTO t4 VALUES (9, 9, 9, 9, 9, 9, "i", "i"), (10, 10, 10, 10, 10, 10, "j", "j");
+
+  let $query= `SELECT query FROM result_queries WHERE id=$id`;
+  enable_query_log;
+
+  eval $query;
+  let $rows= `SELECT COUNT(*) FROM t`;
+  echo ROWS in table t: $rows;
+  inc $id;
+}
+SET MAX_SORT_LENGTH=DEFAULT;
+
+#
+# Cleanup
+#
+DROP TABLE t, t1, t2, t3, t4;
+DROP TABLE queries, result_queries, limits;
+DROP PROCEDURE gen_queries;

=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc	2010-05-14 11:36:27 +0000
+++ b/sql/sql_delete.cc	2010-12-09 04:15:47 +0000
@@ -92,6 +92,18 @@ bool mysql_delete(THD *thd, TABLE_LIST *
     }
   }
 
+  /*
+    Statement-based replication of DELETE ... LIMIT is not safe as
+    order of rows is not defined unless ORDER BY primary_key, so in
+    mixed mode we go to row-based.
+  */
+  if (thd->lex->current_select->select_limit &&
+      select_lex->select_limit->val_int() &&
+      !is_order_deterministic(table_list, conds, (ORDER*)order->first))
+  {
+    thd->lex->set_stmt_unsafe();
+  }
+
   const_cond= (!conds || conds->const_item());
   safe_update=test(thd->options & OPTION_SAFE_UPDATES);
   if (safe_update && const_cond)
@@ -475,19 +487,6 @@ int mysql_prepare_delete(THD *thd, TABLE
   DBUG_ENTER("mysql_prepare_delete");
   List<Item> all_fields;
 
-  /*
-    Statement-based replication of DELETE ... LIMIT is not safe as order of
-    rows is not defined, so in mixed mode we go to row-based.
-
-    Note that we may consider a statement as safe if ORDER BY primary_key
-    is present. However it may confuse users to see very similiar statements
-    replicated differently.
-  */
-  if (thd->lex->current_select->select_limit)
-  {
-    thd->lex->set_stmt_unsafe();
-    thd->set_current_stmt_binlog_row_based_if_mixed();
-  }
   thd->lex->allow_sum_func= 0;
   if (setup_tables_and_check_access(thd, &thd->lex->select_lex.context,
                                     &thd->lex->select_lex.top_join_list,

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2010-03-29 02:32:30 +0000
+++ b/sql/sql_insert.cc	2010-12-09 04:15:47 +0000
@@ -2881,19 +2881,6 @@ bool mysql_insert_select_prepare(THD *th
   DBUG_ENTER("mysql_insert_select_prepare");
 
   /*
-    Statement-based replication of INSERT ... SELECT ... LIMIT is not safe
-    as order of rows is not defined, so in mixed mode we go to row-based.
-
-    Note that we may consider a statement as safe if ORDER BY primary_key
-    is present or we SELECT a constant. However it may confuse users to
-    see very similiar statements replicated differently.
-  */
-  if (lex->current_select->select_limit)
-  {
-    lex->set_stmt_unsafe();
-    thd->set_current_stmt_binlog_row_based_if_mixed();
-  }
-  /*
     SELECT_LEX do not belong to INSERT statement, so we can't add WHERE
     clause if table is VIEW
   */

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2010-05-27 15:13:53 +0000
+++ b/sql/sql_select.cc	2010-12-09 04:15:47 +0000
@@ -910,6 +910,22 @@ JOIN::optimize()
     }
   }
 
+  if (thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
+      thd->lex->sql_command == SQLCOM_REPLACE_SELECT)
+  {
+    /*
+      Statement-based replication of INSERT ... SELECT ... LIMIT is
+      not safe as order of rows is not defined unless ORDER BY
+      primary_key, so in mixed mode we go to row-based.
+    */
+    if (!thd->lex->is_stmt_unsafe() && select_lex->select_limit &&
+        select_lex->select_limit->val_int() &&
+        !is_order_deterministic(join_list, conds, order))
+    {
+      thd->lex->set_stmt_unsafe();
+    }
+  }
+
 #ifdef WITH_PARTITION_STORAGE_ENGINE
   {
     TABLE_LIST *tbl;
@@ -17162,6 +17178,457 @@ bool JOIN::change_result(select_result *
   DBUG_RETURN(FALSE);
 }
 
+bool is_cond_equal(COND *cond)
+{
+  if (cond->type() == Item::FUNC_ITEM &&
+      (((Item_func*)cond)->functype() == Item_func::EQ_FUNC ||
+       ((Item_func*)cond)->functype() == Item_func::EQUAL_FUNC))
+    return TRUE;
+  return FALSE;
+}
+
+bool is_cond_mult_equal(COND *cond)
+{
+  if (cond->type() == Item::FUNC_ITEM &&
+      (((Item_func*)cond)->functype() == Item_func::MULT_EQUAL_FUNC))
+    return TRUE;
+  return FALSE;
+}
+
+/*
+  And-or graph truth propogation algorithm is used to calculate if the
+  statement is ordered or not.
+
+  Nodes:
+    JoinNode - And node, this is the root, successors are a list of
+              ConstOrderedTableNode.
+    ConstOrderedTableNode - Or node, have two TableNode as successors,
+              one for ordered table, and the other for constant table.
+    TableNode - Or node, have a list of KeyNode and one AllColumnsNode
+              as successors.
+    KeyNode - And node, successors are a list of ColumnNode that corresponding
+              to the fields of the key.
+    AllColumnsNode - And node, successors are a list of ColumnNode of all
+              fields of the table.
+    ColumnNode - Or node, represent a field of the table, it will take a
+              TableNode as a successor, which means if a table is true
+              (const or ordered), the all its columns are const or ordered.
+              Successors to other column nodes will be added mutually if
+              there is an equation to that field in the condition. The
+              column nodes for fields that are in the ORDER BY or are
+              equal to constants are added to the init_nodes of the JoinNode,
+              which is used as the initial true values of the propogation.
+ */
+
+/* 
+   Abstract base class for and-or node.
+*/
+class Node :public Sql_alloc {
+public:
+  Node() :todo(0) {}
+  virtual ~Node() {}
+  virtual void add_successor(Node* node)=0;
+  /* Number of successors need to be true to make this node true. */
+  uint todo;
+  /* List of nodes that this node is a successor */
+  List<Node> predecessors;
+};
+
+/*
+  Or node will be true if any of its successors is true.
+ */
+class OrNode :public Node {
+public:
+  OrNode() :Node() {}
+  void add_successor(Node* node)
+  {
+    todo= 1;
+    node->predecessors.push_back(this);
+  }
+};
+
+/*
+  And node can only be true if all its successors are true.
+ */
+class AndNode :public Node {
+public:
+  AndNode() :Node() {}
+  void add_successor(Node* node)
+  {
+    todo++;
+    node->predecessors.push_back(this);
+  }
+};
+
+typedef OrNode ColumnNode;
+typedef AndNode KeyNode;
+typedef AndNode AllColumnsNode;
+
+class TableNode :public OrNode {
+public:
+  TableNode(TABLE* table_arg);
+  ~TableNode();
+  ColumnNode* getColumnNode(Field* field);
+  ColumnNode* createColumnNode(Field* field);
+  AllColumnsNode* createAllColumnsNode();
+  KeyNode* createKeyNode(KEY* key_info);
+private:
+  TABLE* table;
+  ColumnNode** columns;
+};
+
+TableNode::TableNode(TABLE* table_arg)
+  :table(table_arg)
+{
+  columns= new ColumnNode*[table->s->fields];
+  memset(columns, 0, sizeof(ColumnNode*) * table->s->fields);
+  
+  if (table->s->primary_key == MAX_KEY && !table->s->uniques)
+  {
+    add_successor(createAllColumnsNode());
+    return;
+  }
+  uint key;
+  for (key=0; key < table->s->keys; key++)
+  {
+    if ((table->s->key_info[key].flags &
+         (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
+      add_successor(createKeyNode(&table->s->key_info[key]));
+  }
+}
+
+TableNode::~TableNode()
+{
+  delete [] columns;
+}
+
+inline ColumnNode* TableNode::getColumnNode(Field* field)
+{
+  return columns[field->field_index];
+}
+
+inline ColumnNode* TableNode::createColumnNode(Field* field)
+{
+  if (!getColumnNode(field))
+  {
+    ColumnNode* column= new ColumnNode;
+    columns[field->field_index]= column;
+    /*
+      If the table is ORDERED or CONST, then all the columns are
+      ORDERED or CONST, so add the table as an successor of the column
+      node (OrNode).
+    */
+    column->add_successor(this);
+  }
+  return getColumnNode(field);
+}
+
+AllColumnsNode* TableNode::createAllColumnsNode()
+{
+  AllColumnsNode* node= new AllColumnsNode;
+  uint i= 0;
+  for (i=0; i<table->s->fields; i++)
+  {
+    ColumnNode* column= createColumnNode(table->field[i]);
+    node->add_successor(column);
+  }
+  return node;
+}
+
+KeyNode* TableNode::createKeyNode(KEY *key_info)
+{
+  KeyNode* node= new KeyNode;
+  uint key_parts= key_info->key_parts;
+  uint i;
+  for (i=0; i<key_parts; i++)
+  {
+    KEY_PART_INFO *key_part= &key_info->key_part[i];
+    Field *field= table->field[key_part->fieldnr - 1];
+    node->add_successor(createColumnNode(field));
+  }
+  return node;
+}
+
+class ConstOrderedTableNode :public OrNode {
+public:
+  ConstOrderedTableNode(TABLE* table_arg);
+  TABLE* get_table() { return table; }
+  ColumnNode* getOrderedColumnNode(Field* field);
+  ColumnNode* getConstColumnNode(Field* field);
+
+private:
+  TABLE* table;
+  TableNode* orderedTableNode;
+  TableNode* constTableNode;
+};
+
+ConstOrderedTableNode::ConstOrderedTableNode(TABLE* table_arg)
+  :table(table_arg)
+{
+  orderedTableNode= new TableNode(table);
+  constTableNode= new TableNode(table);
+  add_successor(orderedTableNode);
+  add_successor(constTableNode);
+}
+
+inline ColumnNode* ConstOrderedTableNode::getOrderedColumnNode(Field* field)
+{
+  return orderedTableNode->createColumnNode(field);
+}
+
+inline ColumnNode* ConstOrderedTableNode::getConstColumnNode(Field* field)
+{
+  return constTableNode->createColumnNode(field);
+}
+
+class JoinNode :public AndNode {
+public:
+  JoinNode(List<TABLE_LIST>* join_list, COND* cond, ORDER* order);
+  JoinNode(TABLE_LIST* table, COND* cond, ORDER* order);
+  bool is_ordered();
+private:
+  void add_join_list(List<TABLE_LIST>* join_list);
+  void add_table(TABLE* table);
+  ConstOrderedTableNode* getConstOrderedTableNode(TABLE* table);
+  ColumnNode* getOrderedColumnNode(Field* field);
+  ColumnNode* getConstColumnNode(Field* field);
+  void add_ordered_columns(ORDER* order);
+  void add_const_equi_columns(COND* cond);
+  void add_const_column(Field* field);
+  void add_equi_column(Field* left, Field* right);
+private:
+  List<ConstOrderedTableNode> tables;
+  List<Node> init_nodes;
+  ulong max_sort_length;
+};
+
+inline void JoinNode::add_join_list(List<TABLE_LIST>* join_list)
+{
+  List_iterator<TABLE_LIST> it(*join_list);
+  TABLE_LIST *table= join_list->head();
+  COND* on_expr= table->on_expr;
+  while((table= it++))
+    if (table->nested_join)
+      add_join_list(&table->nested_join->join_list);
+    else
+      add_table(table->table);
+  add_const_equi_columns(on_expr);
+}
+
+inline void JoinNode::add_table(TABLE* table)
+{
+  ConstOrderedTableNode* tableNode= new ConstOrderedTableNode(table);
+  add_successor(tableNode);
+  tables.push_back(tableNode);
+}
+
+inline JoinNode::JoinNode(List<TABLE_LIST>* join_list, COND* cond, ORDER* order)
+{
+  DBUG_ASSERT(!join_list->is_empty());
+  max_sort_length= current_thd->variables.max_sort_length;
+  add_join_list(join_list);
+  add_ordered_columns(order);
+  add_const_equi_columns(cond);
+}
+
+inline JoinNode::JoinNode(TABLE_LIST* table, COND* cond, ORDER* order)
+{
+  max_sort_length= current_thd->variables.max_sort_length;
+  add_table(table->table);
+  add_ordered_columns(order);
+  add_const_equi_columns(cond);
+}
+
+inline ConstOrderedTableNode* JoinNode::getConstOrderedTableNode(TABLE* table)
+{
+  List_iterator<ConstOrderedTableNode> it(tables);
+  ConstOrderedTableNode* node;
+  while ((node= it++))
+  {
+    if (node->get_table() == table)
+      return node;
+  }
+  DBUG_ASSERT(0);
+  return NULL;
+}
+
+inline ColumnNode* JoinNode::getOrderedColumnNode(Field* field)
+{
+  return getConstOrderedTableNode(field->table)->getOrderedColumnNode(field);
+}
+
+inline ColumnNode* JoinNode::getConstColumnNode(Field* field)
+{
+  return getConstOrderedTableNode(field->table)->getConstColumnNode(field);
+}
+
+inline void JoinNode::add_const_column(Field* field)
+{
+  ColumnNode* column= getConstColumnNode(field);
+  init_nodes.push_back(column);
+}
+
+void JoinNode::add_equi_column(Field* left, Field* right)
+{
+  ColumnNode* left_column= getConstColumnNode(left);
+  ColumnNode* right_column= getConstColumnNode(right);
+  left_column->add_successor(right_column);
+  right_column->add_successor(left_column);
+
+  left_column= getOrderedColumnNode(left);
+  right_column= getOrderedColumnNode(right);
+  left_column->add_successor(right_column);
+  right_column->add_successor(left_column);
+}
+
+void JoinNode::add_const_equi_columns(COND* cond)
+{
+  if (!cond)
+    return;
+  if (is_cond_or(cond))
+    return;
+  if (is_cond_and(cond))
+  {
+    List<Item> *args= ((Item_cond*) cond)->argument_list();
+    List_iterator<COND> it(*args);
+    COND *c;
+    while ((c= it++))
+      add_const_equi_columns(c);
+    return;
+  }
+  if (is_cond_equal(cond))
+  {
+    uint i;
+    Field *first_field= NULL;
+    Field *second_field= NULL;
+    Item **args= ((Item_func*)cond)->arguments();
+    uint arg_count= ((Item_func*)cond)->argument_count();
+    bool const_value= FALSE;
+
+    DBUG_ASSERT(arg_count == 2);
+
+    for (i=0; i<arg_count; i++)
+    {
+      if (args[i]->real_item()->type() == Item::FIELD_ITEM)
+      {
+        if (!first_field)
+          first_field= ((Item_field*)args[i]->real_item())->field;
+        else
+          second_field= ((Item_field*)args[i]->real_item())->field;
+      }
+      else if (args[i]->real_item()->basic_const_item())
+      {
+        const_value = TRUE;
+      }
+    }
+    if (first_field && const_value)
+      add_const_column(first_field);
+    else if (second_field)
+      add_equi_column(first_field, second_field);
+    return;
+  }
+  if (is_cond_mult_equal(cond))
+  {
+    bool has_const= ((Item_equal*)cond)->get_const();
+    Item_equal_iterator it(*((Item_equal*)cond));
+    Item_field *item;
+    if (has_const)
+    {
+      while ((item= it++))
+        add_const_column(item->field);
+    }
+    else
+    {
+      Item_field *first_item= it++;
+      while ((item= it++))
+        add_equi_column(first_item->field, item->field);
+    }
+  }
+  return;
+}
+
+void JoinNode::add_ordered_columns(ORDER* order)
+{
+  for (; order; order=order->next)
+  {
+    if ((*order->item)->real_item()->type() == Item::FIELD_ITEM)
+    {
+      Field *field=((Item_field*) (*order->item)->real_item())->field;
+      /*
+        If the field length is larger than the max_sort_length, then
+        ORDER BY the field will not be guaranteed to be deterministic.
+       */
+      if (field->field_length > max_sort_length)
+        continue;
+      ColumnNode* column= getOrderedColumnNode(field);
+      init_nodes.push_back(column);
+    }
+  }
+}
+
+bool JoinNode::is_ordered()
+{
+  List<Node> nodes(init_nodes);
+  List_iterator<Node> it(nodes);
+  Node *node;
+
+  while ((node= it++))
+  {
+    node->todo--;
+    if (node->todo == 0)
+    {
+      if (node == this)
+        return true;
+      List_iterator<Node> pit(node->predecessors);
+      Node *pnode;
+      while ((pnode= pit++))
+      {
+        if (pnode->todo)
+          nodes.push_back(pnode);
+      }
+    }
+  }
+  return false;
+}
+
+/*
+  Test if the result order is deterministic for a JOIN table list.
+
+  @retval FALSE not deterministic
+  @retval TRUE deterministic
+ */
+bool is_order_deterministic(List<TABLE_LIST>* join_list,
+                            COND* cond, ORDER* order)
+{
+  /*
+    join_list->is_empty() means this is a UNION with a global LIMIT,
+    always mark such statements as non-deterministic, although it
+    might be deterministic for some cases (for example, UNION DISTINCT
+    with ORDER BY a unique key of both side of the UNION).
+  */
+  if (join_list->is_empty())
+    return FALSE;
+
+  JoinNode root(join_list, cond, order);
+  return root.is_ordered();
+}
+
+/*
+  Test if the result order is deterministic for a single table.
+
+  @retval FALSE not deterministic
+  @retval TRUE deterministic
+ */
+bool is_order_deterministic(TABLE_LIST *table,
+                            COND *cond, ORDER *order)
+{
+  if (order == NULL && cond == NULL)
+    return FALSE;
+
+  JoinNode root(table, cond, order);
+  return root.is_ordered();
+}
+
 /**
   @} (end of group Query_Optimizer)
 */

=== modified file 'sql/sql_select.h'
--- a/sql/sql_select.h	2010-02-26 13:16:46 +0000
+++ b/sql/sql_select.h	2010-12-09 04:15:47 +0000
@@ -794,3 +794,5 @@ inline bool optimizer_flag(THD *thd, uin
   return (thd->variables.optimizer_switch & flag);
 }
 
+bool is_order_deterministic(TABLE_LIST *table_list, COND *cond, ORDER *order);
+bool is_order_deterministic(List<TABLE_LIST> *join_list, COND *cond, ORDER *order);

=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc	2010-05-27 20:07:40 +0000
+++ b/sql/sql_update.cc	2010-12-09 04:15:47 +0000
@@ -248,6 +248,18 @@ int mysql_update(THD *thd,
   if (mysql_prepare_update(thd, table_list, &conds, order_num, order))
     DBUG_RETURN(1);
 
+  /*
+    Statement-based replication of UPDATE ... LIMIT is not safe as
+    order of rows is not defined unless ORDER BY primary_key, so in
+    mixed mode we go to row-based.
+  */
+  if (thd->lex->current_select->select_limit &&
+      select_lex->select_limit->val_int() &&
+      !is_order_deterministic(table_list, conds, order))
+  {
+    thd->lex->set_stmt_unsafe();
+  }
+
   old_covering_keys= table->covering_keys;		// Keys used in WHERE
   /* Check the fields we are going to modify */
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -875,19 +887,6 @@ bool mysql_prepare_update(THD *thd, TABL
   SELECT_LEX *select_lex= &thd->lex->select_lex;
   DBUG_ENTER("mysql_prepare_update");
 
-  /*
-    Statement-based replication of UPDATE ... LIMIT is not safe as order of
-    rows is not defined, so in mixed mode we go to row-based.
-
-    Note that we may consider a statement as safe if ORDER BY primary_key
-    is present. However it may confuse users to see very similiar statements
-    replicated differently.
-  */
-  if (thd->lex->current_select->select_limit)
-  {
-    thd->lex->set_stmt_unsafe();
-    thd->set_current_stmt_binlog_row_based_if_mixed();
-  }
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
   table_list->grant.want_privilege= table->grant.want_privilege= 
     (SELECT_ACL & ~table->grant.privilege);


Attachment: [text/bzr-bundle] bzr/zhenxing.he@sun.com-20101209041547-ry7xvzd1v7n87e62.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (zhenxing.he:3418) Bug#42415He Zhenxing9 Dec