List:Commits« Previous MessageNext Message »
From:Li-Bing.Song Date:January 30 2010 3:13pm
Subject:bzr push into mysql-5.1-bugteam branch (Li-Bing.Song:3342 to 3343) Bug#48321
View as plain text  
 3343 Li-Bing.Song@stripped	2010-01-30
      Bug #48321  CURRENT_USER() incorrectly replicated for DROP/RENAME USER;
                  REVOKE/GRANT; ALTER EVENT.
      
      The following statements support the CURRENT_USER() where a user is needed.
        DROP USER 
        RENAME USER CURRENT_USER() ...
        GRANT ... TO CURRENT_USER()
        REVOKE ... FROM CURRENT_USER()
        ALTER DEFINER = CURRENT_USER() EVENT
      but, When these statements are binlogged, CURRENT_USER() just is binlogged
      as 'CURRENT_USER()', it is not expanded to the real user name. When slave 
      executes the log event, 'CURRENT_USER()' is expand to the user of slave 
      SQL thread, but SQL thread's user name always NULL. This breaks the replication.
      
      After this patch, All above statements are rewritten when they are binlogged.
      The CURRENT_USER() is expanded to the real user's name and host.

    added:
      mysql-test/extra/rpl_tests/rpl_current_user.test
    modified:
      mysql-test/suite/rpl/r/rpl_binlog_grant.result
      mysql-test/suite/rpl/r/rpl_events.result
      mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result
      mysql-test/suite/rpl/r/rpl_sp.result
      mysql-test/suite/rpl/r/rpl_user.result
      mysql-test/suite/rpl/t/rpl_binlog_grant.test
      mysql-test/suite/rpl/t/rpl_events.test
      mysql-test/suite/rpl/t/rpl_user.test
      sql/events.cc
      sql/sql_acl.cc
      sql/sql_lex.h
      sql/sql_yacc.yy
 3342 Georgi Kodinov	2010-01-29 [merge]
      merge

    modified:
      mysql-test/r/openssl_1.result
      mysql-test/std_data/cacert.pem
      mysql-test/std_data/client-cert.pem
      mysql-test/std_data/client-key.pem
      mysql-test/std_data/server-cert.pem
      mysql-test/std_data/server-key.pem
      mysql-test/std_data/server8k-cert.pem
      mysql-test/std_data/server8k-key.pem
      mysql-test/t/openssl_1.test
=== added file 'mysql-test/extra/rpl_tests/rpl_current_user.test'
--- a/mysql-test/extra/rpl_tests/rpl_current_user.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_current_user.test	2010-01-30 12:49:25 +0000
@@ -0,0 +1,127 @@
+--let $count=1
+connection master;
+
+if (`SELECT '$diff_table' = ''`)
+{
+  let $diff_table= mysql.user;
+}
+
+--echo 
+--echo 
+--echo 
+--echo TEST STATEMENT: '$statement'
+--echo --------------------------------------------------------------------------
+
+if (`SELECT '$diff_columns' = ''`)
+{
+  eval CREATE VIEW test.bug48321_v1 AS SELECT user FROM $diff_table
+        WHERE user LIKE 'bug48321%';
+}
+
+if (`SELECT '$diff_columns' <> ''`)
+{
+  eval CREATE VIEW test.bug48321_v1 AS SELECT user, $diff_columns
+       FROM $diff_table WHERE user LIKE 'bug48321%';
+}
+
+while (`SELECT $count < 6`)
+{
+  --echo
+  --echo TEST STATEMENT: '$statement'
+  --echo CASE $count:
+  --echo -------
+
+  let $user2= 'bug48321_2'@'localhost';
+  let $user3= 'bug48321_3'@'localhost';
+
+  let $user1= CURRENT_USER();
+  if (`SELECT '$action'='RENAME'`)
+  {
+    let $user1= $user1 TO 'bug48321_4'@'localhost';
+    let $user2= $user2 TO 'bug48321_5'@'localhost';
+    let $user3= $user3 TO 'bug48321_6'@'localhost';
+  }
+
+  if (`SELECT '$action'='GRANT'`)
+  {
+    let $user1= $user1 IDENTIFIED BY 'user1';
+    let $user3= $user3 IDENTIFIED BY '';
+  }
+
+  if (`SELECT $count=1`)
+  {
+   --echo # Only CURRENT_USER() in the user list of the test statement.
+    let $users_list= $user1;
+  }
+
+  if (`SELECT $count=2`)
+  {
+    --echo # Two users are in the test statement, CURRENT_USER is the first one.
+    let $users_list= $user1, $user2;
+  }
+
+  if (`SELECT $count=3`)
+  {
+    --echo # Two users are in the test statement, CURRENT_USER is the last one.
+    let $users_list= $user2, $user1;
+  }
+
+  if (`SELECT $count=4`)
+  {
+    --echo # Three users are in the test statement, CURRENT_USER is the second one.
+    let $users_list= $user2, $user1, $user3;
+  }
+
+  if (`SELECT $count=5`)
+  {
+    --echo # CURRENT_USER is not in the test statement.
+    let $users_list= $user2, $user3;
+  }
+
+  --echo users_list= $users_list
+  --echo
+  --echo # Connect to master with user1, so user1 always is the current user,
+  --echo # when test statement is runing.
+  eval GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION; 
+  eval CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+  if (`SELECT '$action'='REVOKE'`)
+  {
+    --echo
+    --echo # Grant some privileges to users at first when testing 
+    --echo # 'REVOKE ...' statement.
+    eval GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+         'bug48321_3'@'localhost' WITH GRANT OPTION; 
+    eval GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+         'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+  }
+
+  connect (conn1, 127.0.0.1, 'bug48321_1'@'localhost',,);
+  connection conn1;
+  --echo
+  let $temp= `SELECT "$statement"`;
+  eval $temp;
+  --echo
+
+  disconnect conn1;
+
+  connection master;
+  sync_slave_with_master;
+
+  connection master;
+  let $diff_table_1= master:test.bug48321_v1;
+  let $diff_table_2= slave:test.bug48321_v1;
+  source include/diff_tables.inc;
+  --echo
+
+  --echo # Delete all bug48321% users
+  connection master;
+  DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+  DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+  FLUSH PRIVILEGES;
+
+  inc $count;
+}
+DROP VIEW test.bug48321_v1;

=== modified file 'mysql-test/suite/rpl/r/rpl_binlog_grant.result'
--- a/mysql-test/suite/rpl/r/rpl_binlog_grant.result	2009-05-31 05:44:41 +0000
+++ b/mysql-test/suite/rpl/r/rpl_binlog_grant.result	2010-01-30 12:49:25 +0000
@@ -17,16 +17,15 @@ show grants for x@y;
 Grants for x@y
 GRANT USAGE ON *.* TO 'x'@'y'
 GRANT SELECT ON `d1`.`t` TO 'x'@'y'
-show binlog events;
+show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	4	Format_desc	1	106	Server ver: VERSION, Binlog ver: 4
-master-bin.000001	106	Query	1	193	drop database if exists d1
-master-bin.000001	193	Query	1	272	create database d1
-master-bin.000001	272	Query	1	370	use `d1`; create table t (s1 int) engine=innodb
-master-bin.000001	370	Query	1	436	BEGIN
-master-bin.000001	436	Query	1	521	use `d1`; insert into t values (1)
-master-bin.000001	521	Xid	1	548	COMMIT /* XID */
-master-bin.000001	548	Query	1	633	use `d1`; grant select on t to x@y
+master-bin.000001	#	Query	#	#	drop database if exists d1
+master-bin.000001	#	Query	#	#	create database d1
+master-bin.000001	#	Query	#	#	use `d1`; create table t (s1 int) engine=innodb
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `d1`; insert into t values (1)
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+master-bin.000001	#	Query	#	#	use `d1`; grant select on t to 'x'@'y'
 start transaction;
 insert into t values (2);
 revoke select on t from x@y;
@@ -38,19 +37,18 @@ s1
 show grants for x@y;
 Grants for x@y
 GRANT USAGE ON *.* TO 'x'@'y'
-show binlog events;
+show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	4	Format_desc	1	106	Server ver: VERSION, Binlog ver: 4
-master-bin.000001	106	Query	1	193	drop database if exists d1
-master-bin.000001	193	Query	1	272	create database d1
-master-bin.000001	272	Query	1	370	use `d1`; create table t (s1 int) engine=innodb
-master-bin.000001	370	Query	1	436	BEGIN
-master-bin.000001	436	Query	1	521	use `d1`; insert into t values (1)
-master-bin.000001	521	Xid	1	548	COMMIT /* XID */
-master-bin.000001	548	Query	1	633	use `d1`; grant select on t to x@y
-master-bin.000001	633	Query	1	699	BEGIN
-master-bin.000001	699	Query	1	784	use `d1`; insert into t values (2)
-master-bin.000001	784	Xid	1	811	COMMIT /* XID */
-master-bin.000001	811	Query	1	899	use `d1`; revoke select on t from x@y
+master-bin.000001	#	Query	#	#	drop database if exists d1
+master-bin.000001	#	Query	#	#	create database d1
+master-bin.000001	#	Query	#	#	use `d1`; create table t (s1 int) engine=innodb
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `d1`; insert into t values (1)
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+master-bin.000001	#	Query	#	#	use `d1`; grant select on t to 'x'@'y'
+master-bin.000001	#	Query	#	#	BEGIN
+master-bin.000001	#	Query	#	#	use `d1`; insert into t values (2)
+master-bin.000001	#	Xid	#	#	COMMIT /* XID */
+master-bin.000001	#	Query	#	#	use `d1`; revoke select on t from 'x'@'y'
 drop user x@y;
 drop database d1;

=== modified file 'mysql-test/suite/rpl/r/rpl_events.result'
--- a/mysql-test/suite/rpl/r/rpl_events.result	2009-08-31 02:26:01 +0000
+++ b/mysql-test/suite/rpl/r/rpl_events.result	2010-01-30 12:49:25 +0000
@@ -251,3 +251,45 @@ DROP EVENT event44331_1;
 DROP EVENT event44331_2;
 DROP EVENT event44331_3;
 DROP EVENT event44331_4;
+DROP VIEW IF EXISTS events_view;
+DROP EVENT IF EXISTS event48321_1;
+DROP EVENT IF EXISTS event48321_2;
+DROP EVENT IF EXISTS event48321_3;
+DROP EVENT IF EXISTS event48321_4;
+CREATE VIEW events_view AS
+SELECT EVENT_SCHEMA, EVENT_NAME, DEFINER FROM INFORMATION_SCHEMA.EVENTS
+WHERE EVENT_NAME LIKE 'event48321%';
+CREATE DEFINER=CURRENT_USER() /*!50000 EVENT event48321_1 */
+ON SCHEDULE AT CURRENT_TIMESTAMP
+ON COMPLETION PRESERVE DISABLE
+DO SELECT 48321 as BUG;
+CREATE DEFINER=CURRENT_USER() EVENT event48321_2
+ON SCHEDULE AT CURRENT_TIMESTAMP
+ON COMPLETION PRESERVE DISABLE
+DO SELECT 48321 as BUG;
+CREATE /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3
+ON SCHEDULE AT CURRENT_TIMESTAMP
+ON COMPLETION PRESERVE DISABLE
+DO SELECT 48321 as BUG;
+Comparing tables master:test.events_view and slave:test.events_view
+ALTER DEFINER=CURRENT_USER() EVENT event48321_1 RENAME TO event48321_4;
+ALTER DEFINER=CURRENT_USER() EVENT event48321_2
+ON SCHEDULE AT CURRENT_TIMESTAMP
+ON COMPLETION PRESERVE DISABLE
+DO SELECT 48321 as BUG;
+ALTER /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3
+ON SCHEDULE AT CURRENT_TIMESTAMP
+ON COMPLETION PRESERVE DISABLE
+DO SELECT 48321 as BUG;
+Comparing tables master:test.events_view and slave:test.events_view
+ALTER /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3
+ON SCHEDULE AT CURRENT_TIMESTAMP
+ON COMPLETION PRESERVE DISABLE
+DO SELECT 48321 as BUG; ALTER EVENT event48321_2 ENABLE |
+Comparing tables master:test.events_view and slave:test.events_view
+ALTER EVENT event48321_3 ENABLE;
+Comparing tables master:test.events_view and slave:test.events_view
+DROP EVENT event48321_4;
+DROP EVENT event48321_2;
+DROP EVENT event48321_3;
+DROP VIEW events_view;

=== modified file 'mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result'
--- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result	2009-12-06 01:11:32 +0000
+++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result	2010-01-30 12:49:25 +0000
@@ -750,7 +750,7 @@ test_rpl	e2	root@localhost	SYSTEM	RECURR
 USE test_rpl;
 SHOW EVENTS;
 Db	Name	Definer	Time zone	Type	Execute at	Interval value	Interval field	Starts	Ends	Status	Originator	character_set_client	collation_connection	Database Collation
-test_rpl	e2	@	SYSTEM	RECURRING	NULL	1	#	#	NULL	SLAVESIDE_DISABLED	1	latin1	latin1_swedish_ci	latin1_swedish_ci
+test_rpl	e2	root@localhost	SYSTEM	RECURRING	NULL	1	#	#	NULL	SLAVESIDE_DISABLED	1	latin1	latin1_swedish_ci	latin1_swedish_ci
 ==========MASTER==========
 SELECT COUNT(*) FROM t1;
 COUNT(*)
@@ -1079,7 +1079,7 @@ master-bin.000001	#	Query	1	#	BEGIN
 master-bin.000001	#	Query	1	#	use `test_rpl`; INSERT INTO t1 VALUES(1, 'test1')
 master-bin.000001	#	Xid	1	#	#
 master-bin.000001	#	Query	1	#	use `test_rpl`; CREATE DEFINER=`root`@`localhost` EVENT e1 ON SCHEDULE EVERY '1' SECOND COMMENT 'e_second_comment' DO DELETE FROM t1
-master-bin.000001	#	Query	1	#	use `test_rpl`; ALTER EVENT e1 RENAME TO e2
+master-bin.000001	#	Query	1	#	use `test_rpl`; ALTER DEFINER=`root`@`localhost` EVENT e1 RENAME TO e2
 master-bin.000001	#	Query	1	#	use `test_rpl`; DROP EVENT e2
 master-bin.000001	#	Query	1	#	BEGIN
 master-bin.000001	#	Query	1	#	use `test_rpl`; DELETE FROM t1

=== modified file 'mysql-test/suite/rpl/r/rpl_sp.result'
--- a/mysql-test/suite/rpl/r/rpl_sp.result	2010-01-22 09:37:44 +0000
+++ b/mysql-test/suite/rpl/r/rpl_sp.result	2010-01-30 12:49:25 +0000
@@ -433,9 +433,9 @@ master-bin.000001	#	Query	1	#	use `mysql
 master-bin.000001	#	Query	1	#	use `mysqltest1`; CREATE DEFINER=`root`@`localhost` PROCEDURE `foo3`()
     DETERMINISTIC
 insert into t1 values (15)
-master-bin.000001	#	Query	1	#	use `mysqltest1`; grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1
-master-bin.000001	#	Query	1	#	use `mysqltest1`; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1
-master-bin.000001	#	Query	1	#	use `mysqltest1`; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1
+master-bin.000001	#	Query	1	#	use `mysqltest1`; grant CREATE ROUTINE, EXECUTE on mysqltest1.* to 'zedjzlcsjhd'@'127.0.0.1'
+master-bin.000001	#	Query	1	#	use `mysqltest1`; grant SELECT on mysqltest1.t1 to 'zedjzlcsjhd'@'127.0.0.1'
+master-bin.000001	#	Query	1	#	use `mysqltest1`; grant SELECT, INSERT on mysqltest1.t2 to 'zedjzlcsjhd'@'127.0.0.1'
 master-bin.000001	#	Query	1	#	use `mysqltest1`; CREATE DEFINER=`zedjzlcsjhd`@`127.0.0.1` PROCEDURE `foo4`()
     DETERMINISTIC
 begin
@@ -510,7 +510,7 @@ select * from t1
 master-bin.000001	#	Query	1	#	use `mysqltest1`; drop procedure foo
 master-bin.000001	#	Query	1	#	use `mysqltest1`; drop function fn1
 master-bin.000001	#	Query	1	#	drop database mysqltest1
-master-bin.000001	#	Query	1	#	drop user "zedjzlcsjhd"@127.0.0.1
+master-bin.000001	#	Query	1	#	DROP USER 'zedjzlcsjhd'@'127.0.0.1'
 master-bin.000001	#	Query	1	#	use `test`; drop function if exists f1
 master-bin.000001	#	Query	1	#	use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
     READS SQL DATA
@@ -675,13 +675,13 @@ CREATE DEFINER=`root`@`localhost` PROCED
 insert into t1 values (15)
 /*!*/;
 SET TIMESTAMP=t/*!*/;
-grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1
+grant CREATE ROUTINE, EXECUTE on mysqltest1.* to 'zedjzlcsjhd'@'127.0.0.1'
 /*!*/;
 SET TIMESTAMP=t/*!*/;
-grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1
+grant SELECT on mysqltest1.t1 to 'zedjzlcsjhd'@'127.0.0.1'
 /*!*/;
 SET TIMESTAMP=t/*!*/;
-grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1
+grant SELECT, INSERT on mysqltest1.t2 to 'zedjzlcsjhd'@'127.0.0.1'
 /*!*/;
 SET TIMESTAMP=t/*!*/;
 CREATE DEFINER=`zedjzlcsjhd`@`127.0.0.1` PROCEDURE `foo4`()
@@ -842,7 +842,7 @@ SET TIMESTAMP=t/*!*/;
 drop database mysqltest1
 /*!*/;
 SET TIMESTAMP=t/*!*/;
-drop user "zedjzlcsjhd"@127.0.0.1
+DROP USER 'zedjzlcsjhd'@'127.0.0.1'
 /*!*/;
 use test/*!*/;
 SET TIMESTAMP=t/*!*/;

=== modified file 'mysql-test/suite/rpl/r/rpl_user.result'
--- a/mysql-test/suite/rpl/r/rpl_user.result	2008-03-29 13:00:12 +0000
+++ b/mysql-test/suite/rpl/r/rpl_user.result	2010-01-30 12:49:25 +0000
@@ -39,7 +39,1754 @@ show binlog events from <binlog_start>;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
 master-bin.000001	#	Query	#	#	use `test`; create user 'foo'@'fakehost'
 master-bin.000001	#	Query	#	#	use `test`; create user 'foo'@'fakehost', 'bar'@'fakehost'
-master-bin.000001	#	Query	#	#	use `test`; rename user 'foo'@'fakehost' to 'foofoo'@'fakehost'
-master-bin.000001	#	Query	#	#	use `test`; rename user 'not_exist_user1'@'fakehost' to 'foobar'@'fakehost', 'bar'@'fakehost' to 'barbar'@'fakehost'
-master-bin.000001	#	Query	#	#	use `test`; drop user 'foofoo'@'fakehost'
-master-bin.000001	#	Query	#	#	use `test`; drop user 'not_exist_user1'@'fakehost', 'barbar'@'fakehost'
+master-bin.000001	#	Query	#	#	use `test`; RENAME USER 'foo'@'fakehost' TO 'foofoo'@'fakehost'
+master-bin.000001	#	Query	#	#	use `test`; RENAME USER 'not_exist_user1'@'fakehost' TO 'foobar'@'fakehost', 'bar'@'fakehost' TO 'barbar'@'fakehost'
+master-bin.000001	#	Query	#	#	use `test`; DROP USER 'foofoo'@'fakehost'
+master-bin.000001	#	Query	#	#	use `test`; DROP USER 'not_exist_user1'@'fakehost', 'barbar'@'fakehost'
+
+
+
+TEST STATEMENT: 'RENAME USER $users_list'
+--------------------------------------------------------------------------
+CREATE VIEW test.bug48321_v1 AS SELECT user FROM mysql.user
+WHERE user LIKE 'bug48321%';
+
+TEST STATEMENT: 'RENAME USER $users_list'
+CASE 1:
+-------
+# Only CURRENT_USER() in the user list of the test statement.
+users_list= CURRENT_USER() TO 'bug48321_4'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+RENAME USER CURRENT_USER() TO 'bug48321_4'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'RENAME USER $users_list'
+CASE 2:
+-------
+# Two users are in the test statement, CURRENT_USER is the first one.
+users_list= CURRENT_USER() TO 'bug48321_4'@'localhost', 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+RENAME USER CURRENT_USER() TO 'bug48321_4'@'localhost', 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'RENAME USER $users_list'
+CASE 3:
+-------
+# Two users are in the test statement, CURRENT_USER is the last one.
+users_list= 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', CURRENT_USER() TO 'bug48321_4'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+RENAME USER 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', CURRENT_USER() TO 'bug48321_4'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'RENAME USER $users_list'
+CASE 4:
+-------
+# Three users are in the test statement, CURRENT_USER is the second one.
+users_list= 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', CURRENT_USER() TO 'bug48321_4'@'localhost', 'bug48321_3'@'localhost' TO 'bug48321_6'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+RENAME USER 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', CURRENT_USER() TO 'bug48321_4'@'localhost', 'bug48321_3'@'localhost' TO 'bug48321_6'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'RENAME USER $users_list'
+CASE 5:
+-------
+# CURRENT_USER is not in the test statement.
+users_list= 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', 'bug48321_3'@'localhost' TO 'bug48321_6'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+RENAME USER 'bug48321_2'@'localhost' TO 'bug48321_5'@'localhost', 'bug48321_3'@'localhost' TO 'bug48321_6'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+DROP VIEW test.bug48321_v1;
+
+
+
+TEST STATEMENT: 'DROP USER $users_list'
+--------------------------------------------------------------------------
+CREATE VIEW test.bug48321_v1 AS SELECT user FROM mysql.user
+WHERE user LIKE 'bug48321%';
+
+TEST STATEMENT: 'DROP USER $users_list'
+CASE 1:
+-------
+# Only CURRENT_USER() in the user list of the test statement.
+users_list= CURRENT_USER()
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+DROP USER CURRENT_USER();
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'DROP USER $users_list'
+CASE 2:
+-------
+# Two users are in the test statement, CURRENT_USER is the first one.
+users_list= CURRENT_USER(), 'bug48321_2'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+DROP USER CURRENT_USER(), 'bug48321_2'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'DROP USER $users_list'
+CASE 3:
+-------
+# Two users are in the test statement, CURRENT_USER is the last one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER()
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+DROP USER 'bug48321_2'@'localhost', CURRENT_USER();
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'DROP USER $users_list'
+CASE 4:
+-------
+# Three users are in the test statement, CURRENT_USER is the second one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+DROP USER 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'DROP USER $users_list'
+CASE 5:
+-------
+# CURRENT_USER is not in the test statement.
+users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+DROP USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+DROP VIEW test.bug48321_v1;
+DROP PROCEDURE IF EXISTS f1;
+CREATE PROCEDURE p1() SELECT 1;
+
+
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list'
+--------------------------------------------------------------------------
+CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv
+FROM mysql.user WHERE user LIKE 'bug48321%';
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list'
+CASE 1:
+-------
+# Only CURRENT_USER() in the user list of the test statement.
+users_list= CURRENT_USER()
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER();
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list'
+CASE 2:
+-------
+# Two users are in the test statement, CURRENT_USER is the first one.
+users_list= CURRENT_USER(), 'bug48321_2'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(), 'bug48321_2'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list'
+CASE 3:
+-------
+# Two users are in the test statement, CURRENT_USER is the last one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER()
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', CURRENT_USER();
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list'
+CASE 4:
+-------
+# Three users are in the test statement, CURRENT_USER is the second one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list'
+CASE 5:
+-------
+# CURRENT_USER is not in the test statement.
+users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+DROP VIEW test.bug48321_v1;
+
+
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/'
+--------------------------------------------------------------------------
+CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv
+FROM mysql.user WHERE user LIKE 'bug48321%';
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/'
+CASE 1:
+-------
+# Only CURRENT_USER() in the user list of the test statement.
+users_list= CURRENT_USER()
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER() /*With comment*/;
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/'
+CASE 2:
+-------
+# Two users are in the test statement, CURRENT_USER is the first one.
+users_list= CURRENT_USER(), 'bug48321_2'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER(), 'bug48321_2'@'localhost' /*With comment*/;
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/'
+CASE 3:
+-------
+# Two users are in the test statement, CURRENT_USER is the last one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER()
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', CURRENT_USER() /*With comment*/;
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/'
+CASE 4:
+-------
+# Three users are in the test statement, CURRENT_USER is the second one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost' /*With comment*/;
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM $users_list /*With comment*/'
+CASE 5:
+-------
+# CURRENT_USER is not in the test statement.
+users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' /*With comment*/;
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+DROP VIEW test.bug48321_v1;
+
+
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list'
+--------------------------------------------------------------------------
+CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv
+FROM mysql.user WHERE user LIKE 'bug48321%';
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list'
+CASE 1:
+-------
+# Only CURRENT_USER() in the user list of the test statement.
+users_list= CURRENT_USER()
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ CURRENT_USER();
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list'
+CASE 2:
+-------
+# Two users are in the test statement, CURRENT_USER is the first one.
+users_list= CURRENT_USER(), 'bug48321_2'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ CURRENT_USER(), 'bug48321_2'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list'
+CASE 3:
+-------
+# Two users are in the test statement, CURRENT_USER is the last one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER()
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ 'bug48321_2'@'localhost', CURRENT_USER();
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list'
+CASE 4:
+-------
+# Three users are in the test statement, CURRENT_USER is the second one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ $users_list'
+CASE 5:
+-------
+# CURRENT_USER is not in the test statement.
+users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ 'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+DROP VIEW test.bug48321_v1;
+
+
+
+TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list'
+--------------------------------------------------------------------------
+CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv
+FROM mysql.user WHERE user LIKE 'bug48321%';
+
+TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list'
+CASE 1:
+-------
+# Only CURRENT_USER() in the user list of the test statement.
+users_list= CURRENT_USER()
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM CURRENT_USER();
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list'
+CASE 2:
+-------
+# Two users are in the test statement, CURRENT_USER is the first one.
+users_list= CURRENT_USER(), 'bug48321_2'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM CURRENT_USER(), 'bug48321_2'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list'
+CASE 3:
+-------
+# Two users are in the test statement, CURRENT_USER is the last one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER()
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM 'bug48321_2'@'localhost', CURRENT_USER();
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list'
+CASE 4:
+-------
+# Three users are in the test statement, CURRENT_USER is the second one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM $users_list'
+CASE 5:
+-------
+# CURRENT_USER is not in the test statement.
+users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM 'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+DROP VIEW test.bug48321_v1;
+
+
+
+TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list'
+--------------------------------------------------------------------------
+CREATE VIEW test.bug48321_v1 AS SELECT user, Create_routine_priv
+FROM mysql.user WHERE user LIKE 'bug48321%';
+
+TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list'
+CASE 1:
+-------
+# Only CURRENT_USER() in the user list of the test statement.
+users_list= CURRENT_USER()
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE CREATE ROUTINE ON *.* FROM CURRENT_USER();
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list'
+CASE 2:
+-------
+# Two users are in the test statement, CURRENT_USER is the first one.
+users_list= CURRENT_USER(), 'bug48321_2'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE CREATE ROUTINE ON *.* FROM CURRENT_USER(), 'bug48321_2'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list'
+CASE 3:
+-------
+# Two users are in the test statement, CURRENT_USER is the last one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER()
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE CREATE ROUTINE ON *.* FROM 'bug48321_2'@'localhost', CURRENT_USER();
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list'
+CASE 4:
+-------
+# Three users are in the test statement, CURRENT_USER is the second one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE CREATE ROUTINE ON *.* FROM 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE CREATE ROUTINE ON *.* FROM $users_list'
+CASE 5:
+-------
+# CURRENT_USER is not in the test statement.
+users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE CREATE ROUTINE ON *.* FROM 'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+DROP VIEW test.bug48321_v1;
+
+
+
+TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list'
+--------------------------------------------------------------------------
+CREATE VIEW test.bug48321_v1 AS SELECT user, Routine_name, Proc_priv
+FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+
+TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list'
+CASE 1:
+-------
+# Only CURRENT_USER() in the user list of the test statement.
+users_list= CURRENT_USER()
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER();
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list'
+CASE 2:
+-------
+# Two users are in the test statement, CURRENT_USER is the first one.
+users_list= CURRENT_USER(), 'bug48321_2'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER(), 'bug48321_2'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list'
+CASE 3:
+-------
+# Two users are in the test statement, CURRENT_USER is the last one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER()
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM 'bug48321_2'@'localhost', CURRENT_USER();
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list'
+CASE 4:
+-------
+# Three users are in the test statement, CURRENT_USER is the second one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM 'bug48321_2'@'localhost', CURRENT_USER(), 'bug48321_3'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM $users_list'
+CASE 5:
+-------
+# CURRENT_USER is not in the test statement.
+users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+# Grant some privileges to users at first when testing 
+# 'REVOKE ...' statement.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost',
+'bug48321_3'@'localhost' WITH GRANT OPTION;
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_1'@'localhost',
+'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM 'bug48321_2'@'localhost', 'bug48321_3'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+DROP VIEW test.bug48321_v1;
+
+
+
+TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION'
+--------------------------------------------------------------------------
+CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv, Password
+FROM mysql.user WHERE user LIKE 'bug48321%';
+
+TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION'
+CASE 1:
+-------
+# Only CURRENT_USER() in the user list of the test statement.
+users_list= CURRENT_USER() IDENTIFIED BY 'user1'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1' WITH GRANT OPTION;
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION'
+CASE 2:
+-------
+# Two users are in the test statement, CURRENT_USER is the first one.
+users_list= CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost' WITH GRANT OPTION;
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION'
+CASE 3:
+-------
+# Two users are in the test statement, CURRENT_USER is the last one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1' WITH GRANT OPTION;
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION'
+CASE 4:
+-------
+# Three users are in the test statement, CURRENT_USER is the second one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY ''
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '' WITH GRANT OPTION;
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list WITH GRANT OPTION'
+CASE 5:
+-------
+# CURRENT_USER is not in the test statement.
+users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY ''
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '' WITH GRANT OPTION;
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+DROP VIEW test.bug48321_v1;
+
+
+
+TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION'
+--------------------------------------------------------------------------
+CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv, Password
+FROM mysql.user WHERE user LIKE 'bug48321%';
+
+TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION'
+CASE 1:
+-------
+# Only CURRENT_USER() in the user list of the test statement.
+users_list= CURRENT_USER() IDENTIFIED BY 'user1'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1' /* With Comment */ WITH GRANT OPTION;
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION'
+CASE 2:
+-------
+# Two users are in the test statement, CURRENT_USER is the first one.
+users_list= CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost' /* With Comment */ WITH GRANT OPTION;
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION'
+CASE 3:
+-------
+# Two users are in the test statement, CURRENT_USER is the last one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1' /* With Comment */ WITH GRANT OPTION;
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION'
+CASE 4:
+-------
+# Three users are in the test statement, CURRENT_USER is the second one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY ''
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '' /* With Comment */ WITH GRANT OPTION;
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT ALL PRIVILEGES ON *.* TO $users_list /* With Comment */ WITH GRANT OPTION'
+CASE 5:
+-------
+# CURRENT_USER is not in the test statement.
+users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY ''
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '' /* With Comment */ WITH GRANT OPTION;
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+DROP VIEW test.bug48321_v1;
+
+
+
+TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list'
+--------------------------------------------------------------------------
+CREATE VIEW test.bug48321_v1 AS SELECT user, Select_priv, Update_priv, Create_priv, Drop_priv, Password
+FROM mysql.user WHERE user LIKE 'bug48321%';
+
+TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list'
+CASE 1:
+-------
+# Only CURRENT_USER() in the user list of the test statement.
+users_list= CURRENT_USER() IDENTIFIED BY 'user1'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO CURRENT_USER() IDENTIFIED BY 'user1';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list'
+CASE 2:
+-------
+# Two users are in the test statement, CURRENT_USER is the first one.
+users_list= CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list'
+CASE 3:
+-------
+# Two users are in the test statement, CURRENT_USER is the last one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list'
+CASE 4:
+-------
+# Three users are in the test statement, CURRENT_USER is the second one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY ''
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO $users_list'
+CASE 5:
+-------
+# CURRENT_USER is not in the test statement.
+users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY ''
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+DROP VIEW test.bug48321_v1;
+
+
+
+TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list'
+--------------------------------------------------------------------------
+CREATE VIEW test.bug48321_v1 AS SELECT user, Create_routine_priv
+FROM mysql.user WHERE user LIKE 'bug48321%';
+
+TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list'
+CASE 1:
+-------
+# Only CURRENT_USER() in the user list of the test statement.
+users_list= CURRENT_USER() IDENTIFIED BY 'user1'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT CREATE ROUTINE ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list'
+CASE 2:
+-------
+# Two users are in the test statement, CURRENT_USER is the first one.
+users_list= CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT CREATE ROUTINE ON *.* TO CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list'
+CASE 3:
+-------
+# Two users are in the test statement, CURRENT_USER is the last one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT CREATE ROUTINE ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list'
+CASE 4:
+-------
+# Three users are in the test statement, CURRENT_USER is the second one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY ''
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT CREATE ROUTINE ON *.* TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT CREATE ROUTINE ON *.* TO $users_list'
+CASE 5:
+-------
+# CURRENT_USER is not in the test statement.
+users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY ''
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT CREATE ROUTINE ON *.* TO 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+DROP VIEW test.bug48321_v1;
+DROP PROCEDURE p1;
+
+
+
+TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list'
+--------------------------------------------------------------------------
+CREATE VIEW test.bug48321_v1 AS SELECT user, Routine_name, Proc_priv
+FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+
+TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list'
+CASE 1:
+-------
+# Only CURRENT_USER() in the user list of the test statement.
+users_list= CURRENT_USER() IDENTIFIED BY 'user1'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER() IDENTIFIED BY 'user1';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list'
+CASE 2:
+-------
+# Two users are in the test statement, CURRENT_USER is the first one.
+users_list= CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_2'@'localhost';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list'
+CASE 3:
+-------
+# Two users are in the test statement, CURRENT_USER is the last one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1'
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list'
+CASE 4:
+-------
+# Three users are in the test statement, CURRENT_USER is the second one.
+users_list= 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY ''
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_2'@'localhost', CURRENT_USER() IDENTIFIED BY 'user1', 'bug48321_3'@'localhost' IDENTIFIED BY '';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+
+TEST STATEMENT: 'GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO $users_list'
+CASE 5:
+-------
+# CURRENT_USER is not in the test statement.
+users_list= 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY ''
+
+# Connect to master with user1, so user1 always is the current user,
+# when test statement is runing.
+GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1'@'localhost'
+       WITH GRANT OPTION;
+CREATE USER 'bug48321_2'@'localhost', 'bug48321_3'@'localhost'
+       IDENTIFIED BY 'user3';
+
+GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO 'bug48321_2'@'localhost', 'bug48321_3'@'localhost' IDENTIFIED BY '';
+
+Comparing tables master:test.bug48321_v1 and slave:test.bug48321_v1
+
+# Delete all bug48321% users
+DELETE FROM mysql.user WHERE user LIKE 'bug48321%';
+DELETE FROM mysql.procs_priv WHERE user LIKE 'bug48321%';
+FLUSH PRIVILEGES;
+DROP VIEW test.bug48321_v1;

=== modified file 'mysql-test/suite/rpl/t/rpl_binlog_grant.test'
--- a/mysql-test/suite/rpl/t/rpl_binlog_grant.test	2008-04-05 17:33:42 +0000
+++ b/mysql-test/suite/rpl/t/rpl_binlog_grant.test	2010-01-30 12:49:25 +0000
@@ -25,9 +25,7 @@ grant select on t to x@y;
 #
 rollback;
 show grants for x@y;
---replace_result $VERSION VERSION
---replace_regex /\/\* xid=.* \*\//\/* XID *\//
-show binlog events;
+--source include/show_binlog_events.inc
 start transaction;
 insert into t values (2);
 revoke select on t from x@y;
@@ -37,9 +35,7 @@ revoke select on t from x@y;
 commit;
 select * from t;
 show grants for x@y;
---replace_result $VERSION VERSION
---replace_regex /\/\* xid=.* \*\//\/* XID *\//
-show binlog events;
+--source include/show_binlog_events.inc
 drop user x@y;
 drop database d1;
 --sync_slave_with_master

=== modified file 'mysql-test/suite/rpl/t/rpl_events.test'
--- a/mysql-test/suite/rpl/t/rpl_events.test	2009-08-31 02:26:01 +0000
+++ b/mysql-test/suite/rpl/t/rpl_events.test	2010-01-30 12:49:25 +0000
@@ -105,3 +105,85 @@ DROP EVENT event44331_2;
 DROP EVENT event44331_3;
 DROP EVENT event44331_4;
 sync_slave_with_master;
+
+#
+# BUG#48321
+# This test verifies if the definer is consistent between master and slave,
+# when the event is created or altered with the DEFINER clause that the
+# DEFINER is set to CURRENT_USER()
+#
+connection master;
+--disable_warnings
+DROP VIEW IF EXISTS events_view;
+DROP EVENT IF EXISTS event48321_1;
+DROP EVENT IF EXISTS event48321_2;
+DROP EVENT IF EXISTS event48321_3;
+DROP EVENT IF EXISTS event48321_4;
+--enable_warnings
+
+CREATE VIEW events_view AS
+  SELECT EVENT_SCHEMA, EVENT_NAME, DEFINER FROM INFORMATION_SCHEMA.EVENTS
+  WHERE EVENT_NAME LIKE 'event48321%';
+let $diff_table_1= master:test.events_view;
+let $diff_table_2= slave:test.events_view;
+
+CREATE DEFINER=CURRENT_USER() /*!50000 EVENT event48321_1 */
+  ON SCHEDULE AT CURRENT_TIMESTAMP
+  ON COMPLETION PRESERVE DISABLE
+  DO SELECT 48321 as BUG;
+            
+CREATE DEFINER=CURRENT_USER() EVENT event48321_2
+  ON SCHEDULE AT CURRENT_TIMESTAMP
+  ON COMPLETION PRESERVE DISABLE
+  DO SELECT 48321 as BUG;
+
+CREATE /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3
+  ON SCHEDULE AT CURRENT_TIMESTAMP
+  ON COMPLETION PRESERVE DISABLE
+  DO SELECT 48321 as BUG;
+sync_slave_with_master;
+
+--source include/diff_tables.inc
+
+connection master;
+ALTER DEFINER=CURRENT_USER() EVENT event48321_1 RENAME TO event48321_4;
+
+ALTER DEFINER=CURRENT_USER() EVENT event48321_2
+  ON SCHEDULE AT CURRENT_TIMESTAMP
+  ON COMPLETION PRESERVE DISABLE
+  DO SELECT 48321 as BUG;
+
+ALTER /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3
+  ON SCHEDULE AT CURRENT_TIMESTAMP
+  ON COMPLETION PRESERVE DISABLE
+  DO SELECT 48321 as BUG;
+sync_slave_with_master;
+
+--source include/diff_tables.inc
+
+# Two statements in on query
+connection master;
+DELIMITER |;
+ALTER /*!50000 DEFINER=CURRENT_USER() */ EVENT event48321_3
+  ON SCHEDULE AT CURRENT_TIMESTAMP
+  ON COMPLETION PRESERVE DISABLE
+  DO SELECT 48321 as BUG; ALTER EVENT event48321_2 ENABLE |
+DELIMITER ;|
+sync_slave_with_master;
+
+--source include/diff_tables.inc
+
+#No Event boday
+connection master;
+ALTER EVENT event48321_3 ENABLE;
+sync_slave_with_master;
+
+--source include/diff_tables.inc
+
+connection master;
+DROP EVENT event48321_4;
+DROP EVENT event48321_2;
+DROP EVENT event48321_3;
+DROP VIEW events_view;
+--source include/master-slave-end.inc
+

=== modified file 'mysql-test/suite/rpl/t/rpl_user.test'
--- a/mysql-test/suite/rpl/t/rpl_user.test	2008-02-05 13:52:20 +0000
+++ b/mysql-test/suite/rpl/t/rpl_user.test	2010-01-30 12:49:25 +0000
@@ -54,8 +54,85 @@ drop user 'not_exist_user1'@'fakehost', 
 sync_slave_with_master;
 select Host,User from mysql.user where Host='fakehost';
 
-#
-# show the binlog events on the master
-#
 connection master;
 source include/show_binlog_events.inc;
+
+#
+# BUG#48321
+#
+let $action= RENAME;
+let $statement= RENAME USER \$users_list;
+source extra/rpl_tests/rpl_current_user.test;
+
+let $action= DROP;
+let $statement= DROP USER \$users_list;
+source extra/rpl_tests/rpl_current_user.test;
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS f1;
+--enable_warnings
+CREATE PROCEDURE p1() SELECT 1;
+#REVOKE ALL PRIVILEGES
+let $action= REVOKE;
+let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv;
+let $statement= REVOKE ALL PRIVILEGES, GRANT OPTION FROM \$users_list;
+source extra/rpl_tests/rpl_current_user.test;
+
+#REVOKE ALL PRIVILEGES with comment
+let $action= REVOKE;
+let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv;
+let $statement= REVOKE ALL PRIVILEGES, GRANT OPTION FROM \$users_list /*With comment*/;
+source extra/rpl_tests/rpl_current_user.test;
+
+#REVOKE ALL PRIVILEGES with comment
+let $action= REVOKE;
+let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv;
+let $statement= REVOKE ALL PRIVILEGES, GRANT OPTION FROM /*With comment*/ \$users_list;
+source extra/rpl_tests/rpl_current_user.test;
+
+let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv;
+#REVOKE ON TABLE
+let $statement= REVOKE SELECT, UPDATE, CREATE, DROP ON TABLE *.* FROM \$users_list;
+source extra/rpl_tests/rpl_current_user.test;
+
+#REVOKE ON CREATE ROUTINE
+let $diff_columns= Create_routine_priv;
+let $statement= REVOKE CREATE ROUTINE ON *.* FROM \$users_list;
+source extra/rpl_tests/rpl_current_user.test;
+
+#REVOKE ON ROUTINE
+let $diff_table= mysql.procs_priv;
+let $diff_columns= Routine_name, Proc_priv;
+let $statement= REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM \$users_list;
+source extra/rpl_tests/rpl_current_user.test;
+
+let $diff_table= mysql.user;
+#GRANT ALL PRIVILEGES
+let $action= GRANT;
+let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv, Password;
+let $statement= GRANT ALL PRIVILEGES ON *.* TO \$users_list WITH GRANT OPTION;
+source extra/rpl_tests/rpl_current_user.test;
+
+#GRANT ALL PRIVILEGES with comment
+let $action= GRANT;
+let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Grant_priv, Password;
+let $statement= GRANT ALL PRIVILEGES ON *.* TO \$users_list /* With Comment */ WITH GRANT OPTION;
+source extra/rpl_tests/rpl_current_user.test;
+
+#GRANT ON TABLE
+let $diff_columns= Select_priv, Update_priv, Create_priv, Drop_priv, Password;
+let $statement= GRANT SELECT, UPDATE, CREATE, DROP ON TABLE *.* TO \$users_list;
+source extra/rpl_tests/rpl_current_user.test;
+
+#GRANT ON CREATE ROUTINE
+let $diff_columns= Create_routine_priv;
+let $statement= GRANT CREATE ROUTINE ON *.* TO \$users_list;
+source extra/rpl_tests/rpl_current_user.test;
+
+#GRANT ON ROUTINE
+let $diff_table= mysql.procs_priv;
+let $diff_columns= Routine_name, Proc_priv;
+let $statement= GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO \$users_list;
+
+DROP PROCEDURE p1;
+source extra/rpl_tests/rpl_current_user.test;

=== modified file 'sql/events.cc'
--- a/sql/events.cc	2010-01-25 02:55:05 +0000
+++ b/sql/events.cc	2010-01-30 12:49:25 +0000
@@ -341,31 +341,48 @@ common_1_lev_code:
 }
 
 
-/**
-  Create a new query string for removing executable comments 
-  for avoiding leak and keeping consistency of the execution 
-  on master and slave.
-  
+/*
+  Binlog '{CREATE|ALTER} EVENT' statements.
+  Definer part is always rewritten, for definer can be CURRENT_USER() function.
+
   @param[in] thd                 Thread handler
-  @param[in] buf                 Query string
+  @param[in] create              CREATE or ALTER statement
 
   @return
-             0           ok
-             1           error
+             FASE           ok
+             TRUE           error
 */
-static int
-create_query_string(THD *thd, String *buf)
+static bool event_write_bin_log(THD *thd, bool create)
 {
-  /* Append the "CREATE" part of the query */
-  if (buf->append(STRING_WITH_LEN("CREATE ")))
-    return 1;
-  /* Append definer */
-  append_definer(thd, buf, &(thd->lex->definer->user), &(thd->lex->definer->host));
+  String log_query;
+  if (create)
+  {
+    /* Append the "CREATE" part of the query */
+    if (log_query.append(STRING_WITH_LEN("CREATE ")))
+      return TRUE;
+  }
+  else
+  {
+    /* Append the "ALETR " part of the query */
+    if (log_query.append(STRING_WITH_LEN("ALTER ")))
+      return TRUE;
+  }
+
+  /* Append definer
+     If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER
+     will be written into the binary log as the definer for the SQL thread.
+   */
+  append_definer(thd, &log_query, &(thd->lex->definer->user),
+                 &(thd->lex->definer->host));
+
   /* Append the left part of thd->query after "DEFINER" part */
-  if (buf->append(thd->lex->stmt_definition_begin))
-    return 1;
- 
-  return 0;
+  if (log_query.append(thd->lex->stmt_definition_begin,
+                       thd->lex->stmt_definition_end -
+                       thd->lex->stmt_definition_begin))
+    return TRUE;
+
+  return write_bin_log(thd, TRUE, log_query.c_ptr_safe(), log_query.length())
+          != 0;
 }
 
 /**
@@ -380,8 +397,7 @@ create_query_string(THD *thd, String *bu
   @sa Events::drop_event for the notes about locking, pre-locking
   and Events DDL.
 
-  @retval  FALSE  OK
-  @retval  TRUE   Error (reported)
+  @retval  FALSE  OK @retval  TRUE   Error (reported)
 */
 
 bool
@@ -465,22 +481,7 @@ Events::create_event(THD *thd, Event_par
       binlog the create event unless it's been successfully dropped
     */
     if (!dropped)
-    {
-      /* Binlog the create event. */
-      DBUG_ASSERT(thd->query() && thd->query_length());
-      String log_query;
-      if (create_query_string(thd, &log_query))
-      {
-        sql_print_error("Event Error: An error occurred while creating query string, "
-                        "before writing it into binary log.");
-        /* Restore the state of binlog format */
-        thd->current_stmt_binlog_row_based= save_binlog_row_based;
-        DBUG_RETURN(TRUE);
-      }
-      /* If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER 
-         will be written into the binary log as the definer for the SQL thread. */
-      ret= write_bin_log(thd, TRUE, log_query.c_ptr(), log_query.length());
-    }
+      ret= event_write_bin_log(thd, TRUE);
   }
   pthread_mutex_unlock(&LOCK_event_metadata);
   /* Restore the state of binlog format */
@@ -602,9 +603,7 @@ Events::update_event(THD *thd, Event_par
       if (event_queue)
         event_queue->update_event(thd, parse_data->dbname, parse_data->name,
                                   new_element);
-      /* Binlog the alter event. */
-      DBUG_ASSERT(thd->query() && thd->query_length());
-      ret= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+      ret= event_write_bin_log(thd, FALSE);
     }
   }
   pthread_mutex_unlock(&LOCK_event_metadata);

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2010-01-25 02:55:05 +0000
+++ b/sql/sql_acl.cc	2010-01-30 12:49:25 +0000
@@ -194,6 +194,7 @@ static bool compare_hostname(const acl_h
 			     const char *ip);
 static my_bool acl_load(THD *thd, TABLE_LIST *tables);
 static my_bool grant_load(THD *thd, TABLE_LIST *tables);
+static bool acl_write_bin_log(THD *thd, List <LEX_USER> &list, bool clear_error);
 
 /*
   Convert scrambled password to binary form, according to scramble type, 
@@ -3225,7 +3226,8 @@ int mysql_table_grant(THD *thd, TABLE_LI
 
   if (!result) /* success */
   {
-    result= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+    if (acl_write_bin_log(thd, user_list, TRUE))
+      result= -1;
   }
 
   rw_unlock(&LOCK_grant);
@@ -3401,8 +3403,7 @@ bool mysql_routine_grant(THD *thd, TABLE
 
   if (write_to_binlog)
   {
-    if (write_bin_log(thd, FALSE, thd->query(), thd->query_length()))
-      result= TRUE;
+    result|= acl_write_bin_log(thd, user_list, FALSE);
   }
 
   rw_unlock(&LOCK_grant);
@@ -3531,7 +3532,7 @@ bool mysql_grant(THD *thd, const char *d
 
   if (!result)
   {
-    result= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
+    result= acl_write_bin_log(thd, list, TRUE);
   }
 
   rw_unlock(&LOCK_grant);
@@ -5663,9 +5664,9 @@ static int handle_grant_data(TABLE_LIST 
 }
 
 
-static void append_user(String *str, LEX_USER *user)
+static void append_user(String *str, LEX_USER *user, bool comma= TRUE)
 {
-  if (str->length())
+  if (comma && str->length())
     str->append(',');
   str->append('\'');
   str->append(user->user.str);
@@ -5674,6 +5675,65 @@ static void append_user(String *str, LEX
   str->append('\'');
 }
 
+/*
+  The operations(DROP, RENAME, REVOKE, GRANT) will cause inconsistency between
+  master and slave, when CURRENT_USER() is used. To solve this problem, we
+  construct a new binlog statement in which CURRENT_USER() is replaced by
+  the real user name and host name.
+ */
+static bool acl_write_bin_log(THD *thd, List <LEX_USER> &list, bool clear_error)
+{
+  String log_query;
+  LEX *lex= thd->lex;
+  List_iterator <LEX_USER> user_list(list);
+  LEX_USER *user, *tmp_user;
+
+  if (!mysql_bin_log.is_open())
+    return FALSE;
+
+  if (log_query.append(lex->stmt_begin, lex->stmt_user_begin - lex->stmt_begin))
+    return TRUE;
+  while ((tmp_user= user_list++))
+  {
+    if (!(user= get_current_user(thd, tmp_user)))
+      continue;
+
+    /*
+      No User, but a password?
+      They did GRANT ... TO CURRENT_USER() IDENTIFIED BY ... !
+      Get the current user, and shallow-copy the new password to them!
+    */
+    if (!tmp_user->user.str && tmp_user->password.str)
+      user->password= tmp_user->password;
+
+    if (log_query.append(" ", 1))
+      return TRUE;
+    append_user(&log_query, user, FALSE);
+    /* Only 'GRANT' have password */
+    if (user->password.str)
+    {
+      if (log_query.append(STRING_WITH_LEN(" IDENTIFIED BY ")) ||
+                           log_query.append(STRING_WITH_LEN("PASSWORD ")) ||
+                           log_query.append("'", 1) ||
+                           log_query.append(user->password.str,
+                                            user->password.length) ||
+                           log_query.append("'", 1))
+        return TRUE;
+    }
+    if (log_query.append(",", 1))
+      return TRUE;
+  }
+  /* It is binlogged only when at least one user is in the query */
+  if (log_query.c_ptr()[log_query.length()-1] == ',')
+  {
+    log_query.length(log_query.length()-1);
+    if (log_query.append(lex->stmt_user_end, lex->stmt_end - lex->stmt_user_end))
+      return TRUE;
+    return write_bin_log(thd, clear_error, log_query.c_ptr_safe(),
+                         log_query.length()) != 0;
+  }
+  return FALSE;
+}
 
 /*
   Create a list of users.
@@ -5780,6 +5840,7 @@ bool mysql_drop_user(THD *thd, List <LEX
 {
   int result;
   String wrong_users;
+  String log_query;
   LEX_USER *user_name, *tmp_user_name;
   List_iterator <LEX_USER> user_list(list);
   TABLE_LIST tables[GRANT_TABLES];
@@ -5809,6 +5870,7 @@ bool mysql_drop_user(THD *thd, List <LEX
   rw_wrlock(&LOCK_grant);
   VOID(pthread_mutex_lock(&acl_cache->lock));
 
+  log_query.append(STRING_WITH_LEN("DROP USER"));
   while ((tmp_user_name= user_list++))
   {
     if (!(user_name= get_current_user(thd, tmp_user_name)))
@@ -5816,6 +5878,17 @@ bool mysql_drop_user(THD *thd, List <LEX
       result= TRUE;
       continue;
     }  
+
+    /*
+      The operation will cause inconsistency between master and slave, when
+      CURRENT_USER() is used. To solve this problem, we construct a new
+      binlog statement in which CURRENT_USER() is replaced by the real user
+      name and host name.
+     */
+    log_query.append(STRING_WITH_LEN(" "));
+    append_user(&log_query, user_name, FALSE);
+    log_query.append(STRING_WITH_LEN(","));
+
     if (handle_grant_data(tables, 1, user_name, NULL) <= 0)
     {
       append_user(&wrong_users, user_name);
@@ -5834,7 +5907,13 @@ bool mysql_drop_user(THD *thd, List <LEX
     my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr_safe());
 
   if (some_users_deleted)
-    result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
+  {
+    if (log_query.c_ptr()[log_query.length()-1] == ',')
+    {
+      log_query.length(log_query.length()-1);
+      result|= write_bin_log(thd, FALSE, log_query.c_ptr_safe(), log_query.length());
+    }
+  }
 
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
@@ -5862,6 +5941,7 @@ bool mysql_rename_user(THD *thd, List <L
 {
   int result;
   String wrong_users;
+  String log_query;
   LEX_USER *user_from, *tmp_user_from;
   LEX_USER *user_to, *tmp_user_to;
   List_iterator <LEX_USER> user_list(list);
@@ -5889,6 +5969,7 @@ bool mysql_rename_user(THD *thd, List <L
   rw_wrlock(&LOCK_grant);
   VOID(pthread_mutex_lock(&acl_cache->lock));
 
+  log_query.append(STRING_WITH_LEN("RENAME USER"));
   while ((tmp_user_from= user_list++))
   {
     if (!(user_from= get_current_user(thd, tmp_user_from)))
@@ -5905,6 +5986,18 @@ bool mysql_rename_user(THD *thd, List <L
     DBUG_ASSERT(user_to != 0); /* Syntax enforces pairs of users. */
 
     /*
+      The operation will cause inconsistency between master and slave, when
+      CURRENT_USER() is used. To solve this problem, we construct a new
+      binlog statement in which CURRENT_USER() is replaced by the real user
+      name and host name.
+     */
+    log_query.append(STRING_WITH_LEN(" "));
+    append_user(&log_query, user_from, FALSE);
+    log_query.append(STRING_WITH_LEN(" TO "));
+    append_user(&log_query, user_to, FALSE);
+    log_query.append(STRING_WITH_LEN(","));
+
+    /*
       Search all in-memory structures and grant tables
       for a mention of the new user name.
     */
@@ -5925,9 +6018,15 @@ bool mysql_rename_user(THD *thd, List <L
 
   if (result)
     my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr_safe());
-  
-  if (some_users_renamed && mysql_bin_log.is_open())
-    result |= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
+
+  if (some_users_renamed)
+  {
+    if (log_query.c_ptr()[log_query.length()-1] == ',')
+    {
+      log_query.length(log_query.length()-1);
+      result|= write_bin_log(thd, FALSE, log_query.c_ptr_safe(), log_query.length());
+    }
+  }
 
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
@@ -6117,8 +6216,9 @@ bool mysql_revoke_all(THD *thd,  List <L
 
   VOID(pthread_mutex_unlock(&acl_cache->lock));
 
-  int binlog_error=
-    write_bin_log(thd, FALSE, thd->query(), thd->query_length());
+  int binlog_error= 0;
+  if (acl_write_bin_log(thd, list, FALSE))
+    binlog_error= 1;
 
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);

=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h	2009-09-28 12:41:10 +0000
+++ b/sql/sql_lex.h	2010-01-30 12:49:25 +0000
@@ -1727,6 +1727,8 @@ typedef struct st_lex : public Query_tab
       - CREATE TRIGGER (points to "TRIGGER");
       - CREATE PROCEDURE (points to "PROCEDURE");
       - CREATE FUNCTION (points to "FUNCTION" or "AGGREGATE");
+      - CREATE VIEW(points to "VIEW");
+      - CREATE EVENT(points to "EVENT");
 
     This pointer is required to add possibly omitted DEFINER-clause to the
     DDL-statement before dumping it to the binlog.
@@ -1735,6 +1737,29 @@ typedef struct st_lex : public Query_tab
 
   const char *stmt_definition_end;
 
+  /*
+    stmt_begin is intended to point to the begin of every statement.
+    It is now used in the following statements:
+      - GRANT ALL PRIVELEGES ON *.* (points to "GRANT");
+      - REVOKE ALL PRIVELEGES ON *.* (points to "REVOKE");
+   */
+  const char *stmt_begin;
+  const char *stmt_end;
+
+  /*
+    stmt_user_begin is intended to point to the begin of the user list in
+    the following statements:
+      - GRANT ALL PRIVELEGES ON *.* TO 'username'@'hostname'
+        (points to "'username'");
+      - REVOKE ALL PRIVELEGES ON *.* FROM 'username'@'hostname'
+        (points to "'username'");
+
+    these pointers are required to replace the CURRENT_USER()
+    function by the real user before dumping it to the binlog.
+   */
+  const char *stmt_user_begin;
+  const char *stmt_user_end;
+
   /**
     During name resolution search only in the table list given by 
     Name_resolution_context::first_name_resolution_table and

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2010-01-21 08:10:05 +0000
+++ b/sql/sql_yacc.yy	2010-01-30 12:49:25 +0000
@@ -1562,7 +1562,11 @@ opt_end_of_input:
         ;
 
 verb_clause:
-          statement
+          remember_name statement remember_end
+          {
+            Lex->stmt_begin= $1;
+            Lex->stmt_end= $3;
+          }
         | begin
         ;
 
@@ -5743,7 +5747,7 @@ alter:
           }
           view_tail
           {}
-        | ALTER definer_opt EVENT_SYM sp_name
+        | ALTER definer_opt remember_name EVENT_SYM sp_name
           {
             /* 
               It is safe to use Lex->spname because
@@ -5755,7 +5759,8 @@ alter:
 
             if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD)))
               MYSQL_YYABORT;
-            Lex->event_parse_data->identifier= $4;
+            Lex->event_parse_data->identifier= $5;
+            Lex->stmt_definition_begin= $3;
 
             Lex->sql_command= SQLCOM_ALTER_EVENT;
           }
@@ -5765,7 +5770,7 @@ alter:
           opt_ev_comment
           opt_ev_sql_stmt
           {
-            if (!($6 || $7 || $8 || $9 || $10))
+            if (!($7 || $8 || $9 || $10 || $11))
             {
               my_parse_error(ER(ER_SYNTAX_ERROR));
               MYSQL_YYABORT;
@@ -5826,7 +5831,16 @@ opt_ev_rename_to:
         ;
 
 opt_ev_sql_stmt:
-          /* empty*/ { $$= 0;}
+          /* empty*/
+          {
+            $$= 0;
+            /*
+              Lex->sp_head is not initialized when event body is empty.
+              So we can not use Lex->sp_head->set_stmt_end() to set
+              stmt_definition_end.
+             */
+            Lex->stmt_definition_end= (char*) YYLIP->get_cpp_tok_end();
+          }
         | DO_SYM ev_sql_stmt { $$= 1; }
         ;
 
@@ -11516,6 +11530,7 @@ user:
             $$->user = $1;
             $$->host.str= (char *) "%";
             $$->host.length= 1;
+            Lex->stmt_user_end= YYLIP->get_cpp_ptr();
 
             if (check_string_char_length(&$$->user, ER(ER_USERNAME),
                                          USERNAME_CHAR_LENGTH,
@@ -11528,6 +11543,7 @@ user:
             if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user))))
               MYSQL_YYABORT;
             $$->user = $1; $$->host=$3;
+            Lex->stmt_user_end= YYLIP->get_cpp_ptr();
 
             if (check_string_char_length(&$$->user, ER(ER_USERNAME),
                                          USERNAME_CHAR_LENGTH,
@@ -11537,6 +11553,7 @@ user:
           }
         | CURRENT_USER optional_braces
           {
+            Lex->stmt_user_end= YYLIP->get_cpp_ptr();
             if (!($$=(LEX_USER*) YYTHD->alloc(sizeof(st_lex_user))))
               MYSQL_YYABORT;
             /* 
@@ -12727,9 +12744,10 @@ user_list:
         ;
 
 grant_list:
+          { Lex->stmt_user_begin= YYLIP->get_cpp_ptr(); }
           grant_user
           {
-            if (Lex->users_list.push_back($1))
+            if (Lex->users_list.push_back($2))
               MYSQL_YYABORT;
           }
         | grant_list ',' grant_user
@@ -12742,6 +12760,7 @@ grant_list:
 grant_user:
           user IDENTIFIED_SYM BY TEXT_STRING
           {
+            Lex->stmt_user_end= YYLIP->get_cpp_ptr();
             $$=$1; $1->password=$4;
             if ($4.length)
             {
@@ -12768,7 +12787,10 @@ grant_user:
             }
           }
         | user IDENTIFIED_SYM BY PASSWORD TEXT_STRING
-          { $$= $1; $1->password= $5; }
+          {
+            Lex->stmt_user_end= YYLIP->get_cpp_ptr();
+            $$= $1; $1->password= $5;
+          }
         | user
           { $$= $1; $1->password= null_lex_str; }
         ;


Attachment: [text/bzr-bundle] bzr/li-bing.song@sun.com-20100130124925-o6sfex42b6noyc6x.bundle
Thread
bzr push into mysql-5.1-bugteam branch (Li-Bing.Song:3342 to 3343) Bug#48321Li-Bing.Song30 Jan