diff options
author | unknown <cmiller@zippy.cornsilk.net> | 2008-05-15 19:13:24 -0400 |
---|---|---|
committer | unknown <cmiller@zippy.cornsilk.net> | 2008-05-15 19:13:24 -0400 |
commit | 55012e427bc4b3b6a5ffa070e229c519c8cd0b98 (patch) | |
tree | 9d471bf2b51fee92b75f3377d183d2a680bb91c9 /mysql-test | |
parent | ab6e91cf3af9ef3d69e80420eef1ada05d66b9f7 (diff) | |
download | mariadb-git-55012e427bc4b3b6a5ffa070e229c519c8cd0b98.tar.gz |
Bug#36570: Parse error of CREATE PROCEDURE stmt with comments on \
slave
The stored-routine code took the contents of the (lowest) parser
and copied it directly to the binlog, which causes problems if there
is a special case of interpretation at the parser level -- which
there is, in the "/*!VER */" comments. The trailing "*/" caused
errors on the slave, naturally.
Now, since by that point we have /properly/ created parse-tree (as
the rest of the server should do!) for the stored-routine CREATE, we
can construct a perfect statement from that information, instead of
writing uncertain information from an unknown parser state.
Fortunately, there's already a function nearby that does exactly
that.
---
Update for Bug#36570. Qualify routine names with db name when
writing to the binlog ONLY if the source text is qualified.
mysql-test/r/binlog_innodb.result:
Offsets changed due to quoting.
---
New offset to account for db-qualified names.
mysql-test/r/ctype_cp932_binlog.result:
Offsets changed due to quoting.
---
Qualify routine names with DB. Offsets change also.
mysql-test/r/mysqlbinlog.result:
Case changed in result due to interpretation of data instead of
literal recitation.
---
Qualify procedure name with db.
mysql-test/r/rpl_sp.result:
Offsets changed due to quoting. Added tests.
---
Qualify routine names with DB if qualified in query. Offsets change also.
mysql-test/t/rpl_sp.test:
Add version-limiting quotes to exercise bug#36570. Test that
backtick-quoted identifiers and labels work also.
---
Use different db to show qualification works. Qualify routine names
with DB if qualified in query.
sql/sp.cc:
In create_string, we may not have a sp_name parameter yet, so
instead pass the char* and length of the only member we'd get out
of it.
Having done that, we can use the same function to write the
CREATE (FUNC|TRIG|PROC) statement to the binlog as we always used
to display the statement to the user.
---
Make the db name part of the CREATE string if it is specified.
Specify it in part of writing to the binlog when creating a new
routine.
sql/sp_head.cc:
Set the sp_head m_explicit_name member as the sp_name member is set.
We can not peek at this later, as the sp_name is gone by then.
sql/sp_head.h:
Add a member to track whether the name is qualified with the
database.
Diffstat (limited to 'mysql-test')
-rw-r--r-- | mysql-test/r/binlog_innodb.result | 2 | ||||
-rw-r--r-- | mysql-test/r/ctype_cp932_binlog.result | 8 | ||||
-rw-r--r-- | mysql-test/r/mysqlbinlog.result | 2 | ||||
-rw-r--r-- | mysql-test/r/rpl_sp.result | 99 | ||||
-rw-r--r-- | mysql-test/t/rpl_sp.test | 44 |
5 files changed, 117 insertions, 38 deletions
diff --git a/mysql-test/r/binlog_innodb.result b/mysql-test/r/binlog_innodb.result index 18b4b7c1c93..180b43f42ac 100644 --- a/mysql-test/r/binlog_innodb.result +++ b/mysql-test/r/binlog_innodb.result @@ -34,6 +34,6 @@ END| INSERT INTO t2 VALUES (2),(10+bug23333()); SHOW MASTER STATUS; File Position Binlog_Do_DB Binlog_Ignore_DB -# 184136 +# 184141 DROP FUNCTION bug23333; DROP TABLE t1, t2; diff --git a/mysql-test/r/ctype_cp932_binlog.result b/mysql-test/r/ctype_cp932_binlog.result index 0b4ca93a0dd..b00124b7799 100644 --- a/mysql-test/r/ctype_cp932_binlog.result +++ b/mysql-test/r/ctype_cp932_binlog.result @@ -34,12 +34,12 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 362 Query 1 528 use `test`; CREATE TABLE t4 (s1 CHAR(50) CHARACTER SET latin1, s2 CHAR(50) CHARACTER SET cp932, d DECIMAL(10,2)) -master-bin.000001 528 Query 1 776 use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE bug18293 (IN ins1 CHAR(50), +master-bin.000001 528 Query 1 777 use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `bug18293`(IN ins1 CHAR(50), IN ins2 CHAR(50) CHARACTER SET cp932, IN ind DECIMAL(10,2)) BEGIN INSERT INTO t4 VALUES (ins1, ins2, ind); END -master-bin.000001 776 Query 1 987 use `test`; INSERT INTO t4 VALUES ( NAME_CONST('ins1',_latin1 0x466F6F2773206120426172), NAME_CONST('ins2',_cp932 0xED40ED41ED42), NAME_CONST('ind',47.93)) -master-bin.000001 987 Query 1 1076 use `test`; DROP PROCEDURE bug18293 -master-bin.000001 1076 Query 1 1155 use `test`; DROP TABLE t4 +master-bin.000001 777 Query 1 988 use `test`; INSERT INTO t4 VALUES ( NAME_CONST('ins1',_latin1 0x466F6F2773206120426172), NAME_CONST('ins2',_cp932 0xED40ED41ED42), NAME_CONST('ind',47.93)) +master-bin.000001 988 Query 1 1077 use `test`; DROP PROCEDURE bug18293 +master-bin.000001 1077 Query 1 1156 use `test`; DROP TABLE t4 diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index 469250a6fa2..4fd87861ded 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -268,7 +268,7 @@ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.uniq SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; -CREATE DEFINER=`root`@`localhost` procedure p1() +CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`() begin select 1; end diff --git a/mysql-test/r/rpl_sp.result b/mysql-test/r/rpl_sp.result index 78b0f73b9cf..3f564bf9060 100644 --- a/mysql-test/r/rpl_sp.result +++ b/mysql-test/r/rpl_sp.result @@ -386,7 +386,7 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query 1 # drop database if exists mysqltest1 master-bin.000001 # Query 1 # create database mysqltest1 master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a varchar(100)) -master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` procedure foo() +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `foo`() begin declare b int; set b = 8; @@ -396,20 +396,20 @@ end master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values ( NAME_CONST('b',8)) master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (unix_timestamp()) master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1 -master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` procedure foo2() +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `foo2`() select * from mysqltest1.t1 master-bin.000001 # Query 1 # use `mysqltest1`; alter procedure foo2 contains sql master-bin.000001 # Query 1 # use `mysqltest1`; drop table t1 master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a int) master-bin.000001 # Query 1 # use `mysqltest1`; create table t2 like t1 -master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` procedure foo3() -deterministic +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `foo3`() + DETERMINISTIC insert into t1 values (15) master-bin.000001 # Query 1 # use `mysqltest1`; grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1 master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1 master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1 -master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`zedjzlcsjhd`@`127.0.0.1` procedure foo4() -deterministic +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`zedjzlcsjhd`@`127.0.0.1` PROCEDURE `foo4`() + DETERMINISTIC begin insert into t2 values(3); insert into t1 values (5); @@ -423,8 +423,8 @@ master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (5) 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 procedure foo4 -master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` procedure foo4() -deterministic +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `foo4`() + DETERMINISTIC begin insert into t2 values(20),(20); end @@ -433,9 +433,8 @@ master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo4 master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo2 master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo3 -master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` function fn1(x int) -returns int -deterministic +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` FUNCTION `fn1`(x int) RETURNS int(11) + DETERMINISTIC begin insert into t1 values (x); return x+2; @@ -444,32 +443,27 @@ master-bin.000001 # Query 1 # use `mysqltest1`; delete t1,t2 from t1,t2 master-bin.000001 # Query 1 # use `mysqltest1`; SELECT `mysqltest1`.`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 DEFINER=`root`@`localhost` function fn1() -returns int -no sql +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` FUNCTION `fn1`() RETURNS int(11) + NO SQL begin return unix_timestamp(); end master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1 master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values(fn1()) -master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`zedjzlcsjhd`@`127.0.0.1` function fn2() -returns int -no sql +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`zedjzlcsjhd`@`127.0.0.1` FUNCTION `fn2`() RETURNS int(11) + NO SQL begin return unix_timestamp(); end -master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` function fn3() -returns int -not deterministic -reads sql data +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` FUNCTION `fn3`() RETURNS int(11) + READS SQL DATA begin return 0; end 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 DEFINER=`root`@`localhost` function fn1(x int) -returns int +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` FUNCTION `fn1`(x int) RETURNS int(11) begin insert into t2 values(x),(x); return 10; @@ -482,15 +476,15 @@ master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (1) master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1 master-bin.000001 # Query 1 # use `mysqltest1`; drop trigger trg master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (1) -master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` procedure foo() -not deterministic -reads sql data +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `foo`() + READS SQL DATA select * from t1 master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo master-bin.000001 # Query 1 # use `mysqltest1`; drop function fn1 master-bin.000001 # Query 1 # drop database mysqltest1 master-bin.000001 # Query 1 # drop user "zedjzlcsjhd"@127.0.0.1 -master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` function f1() returns int reads sql data +master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11) + READS SQL DATA begin declare var integer; declare c cursor for select a from v1; @@ -506,12 +500,14 @@ master-bin.000001 # Query 1 # use `test`; drop view v1 master-bin.000001 # Query 1 # use `test`; drop function f1 master-bin.000001 # Query 1 # use `test`; DROP TABLE IF EXISTS t1 master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1(col VARCHAR(10)) -master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE p1(arg VARCHAR(10)) +master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`(arg VARCHAR(10)) INSERT INTO t1 VALUES(arg) master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES( NAME_CONST('arg',_latin1'test')) master-bin.000001 # Query 1 # use `test`; DROP PROCEDURE p1 -master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE p1() SET @a = 1 -master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION f1() RETURNS INT RETURN 0 +master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`() +SET @a = 1 +master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11) +RETURN 0 master-bin.000001 # Query 1 # use `test`; DROP PROCEDURE p1 master-bin.000001 # Query 1 # use `test`; DROP FUNCTION f1 master-bin.000001 # Query 1 # use `test`; drop table t1 @@ -520,9 +516,10 @@ master-bin.000001 # Query 1 # drop database if exists mysqltest2 master-bin.000001 # Query 1 # create database mysqltest master-bin.000001 # Query 1 # create database mysqltest2 master-bin.000001 # Query 1 # use `mysqltest2`; create table t ( t integer ) -master-bin.000001 # Query 1 # use `mysqltest2`; CREATE DEFINER=`root`@`localhost` procedure mysqltest.test() begin end +master-bin.000001 # Query 1 # use `mysqltest2`; CREATE DEFINER=`root`@`localhost` PROCEDURE `mysqltest`.`test`() +begin end master-bin.000001 # Query 1 # use `mysqltest2`; insert into t values ( 1 ) -master-bin.000001 # Query 1 # use `mysqltest2`; CREATE DEFINER=`root`@`localhost` function f1 () returns int +master-bin.000001 # Query 1 # use `mysqltest2`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11) begin insert into t values (1); return 0; @@ -532,3 +529,41 @@ set global log_bin_trust_function_creators=0; set global log_bin_trust_function_creators=0; drop database mysqltest; drop database mysqltest2; +use test; +/*!50001 create procedure `mysqltestbug36570_p1`() */ +begin +select 1; +end| +use mysql| +create procedure test.` mysqltestbug36570_p2`(/*!50001 a int*/)`label`: +begin +select a; +end| +/*!50001 create function test.mysqltestbug36570_f1() */ +returns int +/*!50001 deterministic */ +begin +return 3; +end| +use test| +show procedure status like '%mysqltestbug36570%'; +Db Name Type Definer Modified Created Security_type Comment +test mysqltestbug36570_p2 PROCEDURE root@localhost t t DEFINER +test mysqltestbug36570_p1 PROCEDURE root@localhost t t DEFINER +show create procedure ` mysqltestbug36570_p2`; +Procedure sql_mode Create Procedure + mysqltestbug36570_p2 CREATE DEFINER=`root`@`localhost` PROCEDURE ` mysqltestbug36570_p2`(/*!50001 a int*/) +`label`: +begin +select a; +end +call ` mysqltestbug36570_p2`(42); +a +42 +show function status like '%mysqltestbug36570%'; +Db Name Type Definer Modified Created Security_type Comment +test mysqltestbug36570_f1 FUNCTION root@localhost t t DEFINER +use test; +drop procedure mysqltestbug36570_p1; +drop procedure ` mysqltestbug36570_p2`; +drop function mysqltestbug36570_f1; diff --git a/mysql-test/t/rpl_sp.test b/mysql-test/t/rpl_sp.test index f7cd8907e34..5232717ce54 100644 --- a/mysql-test/t/rpl_sp.test +++ b/mysql-test/t/rpl_sp.test @@ -577,3 +577,47 @@ set global log_bin_trust_function_creators=0; drop database mysqltest; drop database mysqltest2; sync_slave_with_master; + +# +# Bug#36570: Parse error of CREATE PROCEDURE stmt with comments on slave +# +connection master; +use test; +delimiter |; + +/*!50001 create procedure `mysqltestbug36570_p1`() */ +begin + select 1; +end| + +use mysql| +create procedure test.` mysqltestbug36570_p2`(/*!50001 a int*/)`label`: +begin + select a; +end| + +/*!50001 create function test.mysqltestbug36570_f1() */ + returns int + /*!50001 deterministic */ +begin + return 3; +end| +use test| + +delimiter ;| + +sync_slave_with_master; +connection slave; +--replace_column 5 t 6 t +show procedure status like '%mysqltestbug36570%'; +show create procedure ` mysqltestbug36570_p2`; +call ` mysqltestbug36570_p2`(42); + +--replace_column 5 t 6 t +show function status like '%mysqltestbug36570%'; + +connection master; +use test; +drop procedure mysqltestbug36570_p1; +drop procedure ` mysqltestbug36570_p2`; +drop function mysqltestbug36570_f1; |