##############################################################################
# BUG#48321 CURRENT_USER() incorrectly replicated for DROP/RENAME USER,
# REVOKE, GRANT, ALTER EVENT
#
# Calling CURRENT_USER() results into inconsistency between slave and master,
# as the slave SQL thread has different user with common users.
#
# After the patch for bug#48321, session's user will be written into query log
# event if CURRENT_USER() is called in 'DROP/RENAME USER', 'REVOKE', 'GRANT',
# 'ALTER EVENT'.
#
##############################################################################

source include/have_binlog_format_statement.inc;

--let $rpl_topology= 1->2->3
--source include/rpl_init.inc

--let $rpl_connection_name= master
--let $rpl_server_number= 1
--source include/rpl_connect.inc

--let $rpl_connection_name= slave
--let $rpl_server_number= 2
--source include/rpl_connect.inc

--disable_query_log
--connection server_1
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.*");
--connection server_2
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.*");
--connection server_3
call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.*");
--enable_query_log

--connection master

CREATE TABLE t1(c1 char(100));
CREATE VIEW test.v_user AS SELECT * FROM mysql.user WHERE User LIKE 'bug48321%';
CREATE VIEW test.v_tables_priv AS SELECT * FROM mysql.tables_priv WHERE User LIKE 'bug48321%';
CREATE VIEW test.v_procs_priv AS SELECT * FROM mysql.procs_priv WHERE User LIKE 'bug48321%';
CREATE VIEW test.v_event AS SELECT definer FROM mysql.event WHERE name = 'e1';
CREATE PROCEDURE p1() SELECT 1;
--echo # bug48321_1-01234 has the max length(16) of user.
CREATE USER 'bug48321_1-01234'@'localhost';
GRANT ALL PRIVILEGES ON *.* TO 'bug48321_1-01234'@'localhost' WITH GRANT OPTION; 

--echo
--echo # Test the max lengths of user and host names
--echo # the user name is too long
--error ER_WRONG_STRING_LENGTH
GRANT CREATE USER ON *.* TO '012345678901234567890123456789012345678901234567890123456789012345678901234567890'@'fakehost';
--echo # the host name is too long
--error ER_WRONG_STRING_LENGTH
GRANT CREATE USER ON *.* TO 'fakename'@'0123456789012345678901234567890123456789012345678901234567890';

--echo
--echo # User 'bug48321_1-01234' connects to master by conn1
connect (conn1, 127.0.0.1, 'bug48321_1-01234'@'localhost',,);
connection conn1;
--echo # Verify 'REVOKE ALL' statement
REVOKE ALL PRIVILEGES, GRANT OPTION FROM CURRENT_USER();
--source include/rpl_sync.inc
let $diff_tables= server_1:v_user, server_2:v_user, server_3:v_user;
source include/diff_tables.inc;

--echo 
--echo # Verify 'GRANT ... ON TABLE ...' statement
GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER();
--source include/rpl_sync.inc
let $diff_tables= server_1:v_tables_priv, server_2:v_tables_priv, server_3:v_tables_priv;
source include/diff_tables.inc;

--echo 
--echo # Verify 'GRANT ... ON PROCEDURE...' statement
GRANT ALTER ROUTINE, EXECUTE ON PROCEDURE p1 TO CURRENT_USER();
--source include/rpl_sync.inc
let $diff_tables= server_1:v_procs_priv, server_2:v_procs_priv, server_3:v_procs_priv;
source include/diff_tables.inc;

--echo 
--echo # Verify 'GRANT ... ON *.* ...' statement
GRANT ALL PRIVILEGES ON *.* TO CURRENT_USER() WITH GRANT OPTION;
--source include/rpl_sync.inc
let $diff_tables= server_1:v_procs_priv, server_2:v_procs_priv, server_3:v_procs_priv;
source include/diff_tables.inc;

--echo 
--echo # Verify 'REVOKE ... ON TABLE ...' statement
REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER();
--source include/rpl_sync.inc
let $diff_tables= server_1:v_tables_priv, server_2:v_tables_priv, server_3:v_tables_priv;
source include/diff_tables.inc;

--echo 
--echo # Verify 'REVOKE ... ON PROCEDURE...' statement
REVOKE ALTER ROUTINE, EXECUTE ON PROCEDURE p1 FROM CURRENT_USER();
--source include/rpl_sync.inc
let $diff_tables= server_1:v_procs_priv, server_2:v_procs_priv, server_3:v_procs_priv;
source include/diff_tables.inc;

--echo 
--echo # Verify 'REVOKE ... ON *.* ...' statement
REVOKE ALL PRIVILEGES ON *.* FROM CURRENT_USER();
--source include/rpl_sync.inc
let $diff_tables= server_1:v_user, server_2:v_user, server_3:v_user;
source include/diff_tables.inc;

--echo 
--echo # Verify 'GRANT ...' statement in the procedure
CREATE PROCEDURE my_grant()
  GRANT CREATE, INSERT, SELECT ON TABLE test.t1 TO CURRENT_USER();
call my_grant;
--source include/rpl_sync.inc
let $diff_tables= server_1:v_tables_priv, server_2:v_tables_priv, server_3:v_tables_priv;
source include/diff_tables.inc;

--echo 
--echo # Verify 'REVOKE ... ON TABLE ...' statement in the procedure
CREATE PROCEDURE my_revoke()
  REVOKE CREATE, INSERT, SELECT ON TABLE t1 FROM CURRENT_USER();
call my_revoke;
--source include/rpl_sync.inc
let $diff_tables= server_1:v_tables_priv, server_2:v_tables_priv, server_3:v_tables_priv;
source include/diff_tables.inc;

--echo 
--echo # Verify 'RENAME USER ...' statement
RENAME USER CURRENT_USER TO 'bug48321_2'@'localhost';
--source include/rpl_sync.inc
let $diff_tables= server_1:v_user, server_2:v_user, server_3:v_user;
source include/diff_tables.inc;

disconnect conn1;

--echo 
--echo # Verify 'DROP USER ...' statement
connection master;
GRANT CREATE USER ON *.* TO 'bug48321_2'@'localhost';
connect (conn1, 127.0.0.1, 'bug48321_2'@'localhost',,);
connection conn1;
DROP USER CURRENT_USER();
--source include/rpl_sync.inc
let $diff_tables= server_1:v_user, server_2:v_user, server_3:v_user;
source include/diff_tables.inc;

--echo 
--echo # Verify 'ALTER EVENT...' statement
connection master;
CREATE EVENT e1 ON SCHEDULE EVERY 1 DAY DO SELECT * FROM t1;

--echo # Explicitly assign CURRENT_USER() to definer
ALTER DEFINER=CURRENT_USER() EVENT e1 ENABLE;
--source include/rpl_sync.inc
let $diff_tables= server_1:v_event, server_2:v_event, server_3:v_event;
source include/diff_tables.inc;

--echo
--echo # Session user will be set as definer, if the statement does not assign
--echo # a definer
ALTER EVENT e1 ENABLE;
--source include/rpl_sync.inc
let $diff_tables= server_1:v_event, server_2:v_event, server_3:v_event;
source include/diff_tables.inc;

--echo
--echo # Verify that this patch does not affect the calling of CURRENT_USER() 
--echo # in the other statements
connection master;
INSERT INTO t1 VALUES(CURRENT_USER()), ('1234');
SELECT * FROM t1;
sync_slave_with_master;
SELECT * FROM t1;
sync_slave_with_master server_3;
SELECT * FROM t1;

connection master;
UPDATE t1 SET c1=CURRENT_USER() WHERE c1='1234';
SELECT * FROM t1;
sync_slave_with_master;
SELECT * FROM t1;
sync_slave_with_master server_3;
SELECT * FROM t1;

connection master;
DELETE FROM t1 WHERE c1=CURRENT_USER();
SELECT * FROM t1;
sync_slave_with_master;
SELECT * FROM t1;
sync_slave_with_master server_3;
SELECT * FROM t1;

connection master;
CREATE TABLE t2(c1 char(100));

DELIMITER |;
CREATE FUNCTION my_user() RETURNS VARCHAR(64) 
  SQL SECURITY INVOKER 
BEGIN
  INSERT INTO t2 VALUES(CURRENT_USER());
  RETURN CURRENT_USER();
END |
DELIMITER ;|

INSERT INTO t1 VALUES(my_user());
SELECT * FROM t1;
SELECT * FROM t2;
sync_slave_with_master;
SELECT * FROM t1;
SELECT * FROM t2;
sync_slave_with_master server_3;
SELECT * FROM t1;
SELECT * FROM t2;

--echo
--echo # END
connection master;
DROP TABLE t1, t2;
DROP VIEW v_user, v_tables_priv, v_procs_priv, v_event; 
DROP PROCEDURE p1;
DROP PROCEDURE my_grant;
DROP PROCEDURE my_revoke;
DROP FUNCTION my_user;
DROP EVENT e1;
--source include/rpl_end.inc
