From: Date: February 18 2006 5:26pm Subject: bk commit into 5.0 tree (guilhem:1.2062) BUG#14769 List-Archive: http://lists.mysql.com/commits/2851 X-Bug: 14769 Message-Id: <200602181626.k1IGQZC4018199@gbichot3.local> Below is the list of changes that have just been committed into a local 5.0 repository of guilhem. When guilhem does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet 1.2062 06/02/18 17:26:30 guilhem@stripped +5 -0 Fix for BUG#14769 "Function fails to replicate if fails half-way (slave stops)": if the function, invoked in a non-binlogged caller (e.g. SELECT, DO), failed half-way on the master, slave would stop and complain that error code between him and master mismatch. To solve this, when a stored function is invoked in a non-binlogged caller (e.g. SELECT, DO), we binlog the function call as SELECT instead of as DO (see revision comment of sp_head.cc for more). And: minor wording change in the help text. This cset will cause conflicts in 5.1, I'll merge. sql/sp_head.cc 1.201 06/02/18 17:26:26 guilhem@stripped +3 -9 When a function updates data and is called from a non-binlogged statement (SELECT, DO), we binlog it as SELECT myfunc(), and not DO myfunc() like before. sql/mysqld.cc 1.534 06/02/18 17:26:25 guilhem@stripped +2 -2 function -> stored function (change suggested by Paul) mysql-test/t/rpl_sp.test 1.12 06/02/18 17:26:25 guilhem@stripped +5 -7 test for more half-failed functions with DO and SELECT, to test the bug of this changeset. cleanup at the end. mysql-test/t/rpl_sp-slave.opt 1.3 06/02/18 17:26:25 guilhem@stripped +1 -1 bug just fixed so option not needed mysql-test/r/rpl_sp.result 1.16 06/02/18 17:26:25 guilhem@stripped +13 -8 result update # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: guilhem # Host: gbichot3.local # Root: /home/mysql_src/mysql-5.0 --- 1.533/sql/mysqld.cc 2006-02-14 05:22:02 +01:00 +++ 1.534/sql/mysqld.cc 2006-02-18 17:26:25 +01:00 @@ -4923,8 +4923,8 @@ */ {"log-bin-trust-function-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS, "If equal to 0 (the default), then when --log-bin is used, creation of " - "a function is allowed only to users having the SUPER privilege and only " - "if this function may not break binary logging.", + "a stored function is allowed only to users having the SUPER privilege and" + " only if this function may not break binary logging.", (gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"log-error", OPT_ERROR_LOG_FILE, "Error log file.", --- 1.15/mysql-test/r/rpl_sp.result 2006-01-20 15:21:33 +01:00 +++ 1.16/mysql-test/r/rpl_sp.result 2006-02-18 17:26:25 +01:00 @@ -233,20 +233,25 @@ delete from t2; alter table t2 add unique (a); drop function fn1; -create function fn1() +create function fn1(x int) returns int begin -insert into t2 values(20),(20); +insert into t2 values(x),(x); return 10; end| -select fn1(); +do fn1(100); +Warnings: +Error 1062 Duplicate entry '100' for key 1 +select fn1(20); ERROR 23000: Duplicate entry '20' for key 1 select * from t2; a 20 +100 select * from t2; a 20 +100 create trigger trg before insert on t1 for each row set new.a= 10; ERROR 42000: Access denied; you need the SUPER privilege for this operation delete from t1; @@ -324,7 +329,7 @@ return x+2; end master-bin.000001 # Query 1 # use `mysqltest1`; delete t1,t2 from t1,t2 -master-bin.000001 # Query 1 # use `mysqltest1`; DO `fn1`(20) +master-bin.000001 # Query 1 # use `mysqltest1`; SELECT `fn1`(20) master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(fn1(21)) master-bin.000001 # Query 1 # use `mysqltest1`; drop function fn1 master-bin.000001 # Query 1 # use `mysqltest1`; create function fn1() @@ -351,13 +356,14 @@ master-bin.000001 # Query 1 # use `mysqltest1`; delete from t2 master-bin.000001 # Query 1 # use `mysqltest1`; alter table t2 add unique (a) master-bin.000001 # Query 1 # use `mysqltest1`; drop function fn1 -master-bin.000001 # Query 1 # use `mysqltest1`; create function fn1() +master-bin.000001 # Query 1 # use `mysqltest1`; create function fn1(x int) returns int begin -insert into t2 values(20),(20); +insert into t2 values(x),(x); return 10; end -master-bin.000001 # Query 1 # use `mysqltest1`; DO `fn1`() +master-bin.000001 # Query 1 # use `mysqltest1`; SELECT `fn1`(100) +master-bin.000001 # Query 1 # use `mysqltest1`; SELECT `fn1`(20) master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1 master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` trigger trg before insert on t1 for each row set new.a= 10 master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (1) @@ -415,4 +421,3 @@ test DROP PROCEDURE p1; drop table t1; -reset master; --- 1.2/mysql-test/t/rpl_sp-slave.opt 2005-11-10 17:50:43 +01:00 +++ 1.3/mysql-test/t/rpl_sp-slave.opt 2006-02-18 17:26:25 +01:00 @@ -1 +1 @@ ---log_bin_trust_routine_creators=0 --slave-skip-errors=1062 +--log_bin_trust_routine_creators=0 --- 1.11/mysql-test/t/rpl_sp.test 2006-01-20 15:21:33 +01:00 +++ 1.12/mysql-test/t/rpl_sp.test 2006-02-18 17:26:25 +01:00 @@ -294,21 +294,19 @@ drop function fn1; delimiter |; -create function fn1() +create function fn1(x int) returns int begin - insert into t2 values(20),(20); + insert into t2 values(x),(x); return 10; end| delimiter ;| -# Because of BUG#14769 the following statement requires that we start -# slave with --slave-skip-errors=1062. When that bug is fixed, that -# option can be removed. +do fn1(100); --error 1062 -select fn1(); +select fn1(20); select * from t2; sync_slave_with_master; @@ -440,4 +438,4 @@ # cleanup connection master; drop table t1; -reset master; +sync_slave_with_master; --- 1.200/sql/sp_head.cc 2006-02-06 14:09:07 +01:00 +++ 1.201/sql/sp_head.cc 2006-02-18 17:26:26 +01:00 @@ -736,13 +736,7 @@ Statements that have is_update_query(stmt) == FALSE (e.g. SELECTs) are not written into binary log. Instead we catch function calls the statement makes and write it into binary log separately (see #3). - - We actually can easily write SELECT statements into the binary log in the - right order (we don't have issues with const tables being unlocked early - because SELECTs that use FUNCTIONs unlock all tables at once) We don't do - it because replication slave thread currently can't execute SELECT - statements. Fixing this is on the TODO. - + 2. PROCEDURE calls CALL statements are not written into binary log. Instead @@ -763,7 +757,7 @@ function execution (grep for start_union_events and stop_union_events) If the answers are No and Yes, we write the function call into the binary - log as "DO spfunc(, , ...)" + log as "SELECT spfunc(, , ...)". 4. Miscellaneous issues. @@ -1310,7 +1304,7 @@ char buf[256]; String bufstr(buf, sizeof(buf), &my_charset_bin); bufstr.length(0); - bufstr.append(STRING_WITH_LEN("DO ")); + bufstr.append(STRING_WITH_LEN("SELECT ")); append_identifier(thd, &bufstr, m_name.str, m_name.length); bufstr.append('('); for (uint i=0; i < argcount; i++)