===== sql/sql_parse.cc 1.612 vs edited =====
--- mysql-5.0/sql/sql_parse.cc.orig	2007-04-01 15:52:55 +04:00
+++ mysql-5.0/sql/sql_parse.cc	2007-04-01 06:52:47 +04:00
@@ -4033,6 +4033,8 @@
     if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
         check_global_access(thd,CREATE_USER_ACL))
       break;
+    if (end_active_trans(thd))
+      goto error;
     /* Conditionally writes to binlog */
     if (!(res = mysql_revoke_all(thd, lex->users_list)))
       send_ok(thd);
@@ -4049,6 +4051,8 @@
                      select_lex->db ? is_schema_db(select_lex->db) : 0))
       goto error;
 
+    if (end_active_trans(thd))
+      goto error;
     if (thd->security_ctx->user)              // If not replication
     {
       LEX_USER *user, *tmp_user;
===== sql/sp_head.cc 1.239 vs edited =====
--- mysql-5.0/sql/sp_head.cc.orig	2007-04-01 15:52:55 +04:00
+++ mysql-5.0/sql/sp_head.cc	2007-04-01 06:52:47 +04:00
@@ -242,11 +242,14 @@
   case SQLCOM_CREATE_TRIGGER:
   case SQLCOM_CREATE_USER:
   case SQLCOM_ALTER_TABLE:
+  case SQLCOM_GRANT:
+  case SQLCOM_REVOKE:
   case SQLCOM_BEGIN:
   case SQLCOM_RENAME_TABLE:
   case SQLCOM_RENAME_USER:
   case SQLCOM_DROP_INDEX:
   case SQLCOM_DROP_DB:
+  case SQLCOM_REVOKE_ALL:
   case SQLCOM_DROP_USER:
   case SQLCOM_DROP_VIEW:
   case SQLCOM_DROP_TRIGGER:
===== mysql-test/t/sp-error.test 1.113 vs edited =====
--- mysql-5.0/mysql-test/t/sp-error.test.orig	2007-04-01 15:52:53 +04:00
+++ mysql-5.0/mysql-test/t/sp-error.test	2007-04-01 06:52:47 +04:00
@@ -1383,6 +1383,21 @@
 CREATE FUNCTION bug_13627_f() returns int BEGIN create user 'mysqltest_1'; return 1; END |
 
 -- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
+CREATE TRIGGER bug21975 BEFORE INSERT ON t1 FOR EACH ROW BEGIN grant select on t1 to 'mysqltest_1'; END |
+-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
+CREATE FUNCTION bug21975() returns int BEGIN grant select on t1 to 'mysqltest_1'; return 1; END |
+
+-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
+CREATE TRIGGER bug21975 BEFORE INSERT ON t1 FOR EACH ROW BEGIN revoke select on t1 from 'mysqltest_1'; END |
+-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
+CREATE FUNCTION bug21975() returns int BEGIN revoke select on t1 from 'mysqltest_1'; return 1; END |
+
+-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
+CREATE TRIGGER bug21975 BEFORE INSERT ON t1 FOR EACH ROW BEGIN revoke all privileges on *.* from 'mysqltest_1'; END |
+-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
+CREATE FUNCTION bug21975() returns int BEGIN revoke all privileges on *.* from 'mysqltest_1'; return 1; END |
+
+-- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
 CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop user 'mysqltest_1'; END |
 -- error ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
 CREATE FUNCTION bug_13627_f() returns int BEGIN drop user 'mysqltest_1'; return 1; END |
===== mysql-test/r/sp-error.result 1.112 vs edited =====
--- mysql-5.0/mysql-test/r/sp-error.result.orig	2007-04-01 15:52:52 +04:00
+++ mysql-5.0/mysql-test/r/sp-error.result	2007-04-01 06:52:47 +04:00
@@ -969,6 +969,18 @@
 ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
 CREATE FUNCTION bug_13627_f() returns int BEGIN create user 'mysqltest_1'; return 1; END |
 ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
+CREATE TRIGGER bug21975 BEFORE INSERT ON t1 FOR EACH ROW BEGIN grant select on t1 to 'mysqltest_1'; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
+CREATE FUNCTION bug21975() returns int BEGIN grant select on t1 to 'mysqltest_1'; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
+CREATE TRIGGER bug21975 BEFORE INSERT ON t1 FOR EACH ROW BEGIN revoke select on t1 from 'mysqltest_1'; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
+CREATE FUNCTION bug21975() returns int BEGIN revoke select on t1 from 'mysqltest_1'; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
+CREATE TRIGGER bug21975 BEFORE INSERT ON t1 FOR EACH ROW BEGIN revoke all privileges on *.* from 'mysqltest_1'; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
+CREATE FUNCTION bug21975() returns int BEGIN revoke all privileges on *.* from 'mysqltest_1'; return 1; END |
+ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
 CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN drop user 'mysqltest_1'; END |
 ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger.
 CREATE FUNCTION bug_13627_f() returns int BEGIN drop user 'mysqltest_1'; return 1; END |
===== New file: mysql-test/t/grant-binlog.test =====
--- /dev/null	2007-03-24 07:53:03 +03:00
+++ mysql-5.0/mysql-test/t/grant-binlog.test	2007-04-01 06:36:42 +04:00
@@ -0,0 +1,39 @@
+-- source include/have_innodb.inc
+-- source include/not_embedded.inc
+
+let $VERSION=`select version()`;
+
+# Bug #21975: grant/revoke statements in transaction
+# used to disappear from binlog upon rallback.
+# Now GRANT/REVOKE do implicitly commit 
+# transaction
+
+--disable-warnings
+drop database if exists d1;
+create database d1;
+use d1;
+create table t (s1 int) engine=innodb;
+set @@autocommit=0;
+start transaction;
+insert into t values (1);
+grant select on t to x@y;
+# 
+# There is no active transaction here
+#
+rollback; 
+show grants for x@y;
+--replace_result $VERSION VERSION
+show binlog events;
+start transaction;
+insert into t values (2);
+revoke select on t from x@y;
+# 
+# There is no active transaction here
+#
+commit;
+select * from t;
+show grants for x@y;
+--replace_result $VERSION VERSION
+show binlog events;
+drop user x@y;
+drop database d1;
===== New file: mysql-test/r/grant-binlog.result =====
--- /dev/null	2007-03-24 07:53:03 +03:00
+++ mysql-5.0/mysql-test/r/grant-binlog.result	2007-04-01 15:47:03 +04:00
@@ -0,0 +1,52 @@
+drop database if exists d1;
+Warnings:
+Note	1008	Can't drop database 'd1'; database doesn't exist
+create database d1;
+use d1;
+create table t (s1 int) engine=innodb;
+set @@autocommit=0;
+start transaction;
+insert into t values (1);
+grant select on t to x@y;
+rollback;
+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;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	4	Format_desc	1	98	Server ver: VERSION, Binlog ver: 4
+master-bin.000001	98	Query	1	185	drop database if exists d1
+master-bin.000001	185	Query	1	264	create database d1
+master-bin.000001	264	Query	1	362	use `d1`; create table t (s1 int) engine=innodb
+master-bin.000001	362	Query	1	428	use `d1`; BEGIN
+master-bin.000001	428	Query	1	85	use `d1`; insert into t values (1)
+master-bin.000001	513	Xid	1	540	COMMIT /* xid=11 */
+master-bin.000001	540	Query	1	625	use `d1`; grant select on t to x@y
+start transaction;
+insert into t values (2);
+revoke select on t from x@y;
+commit;
+select * from t;
+s1
+1
+2
+show grants for x@y;
+Grants for x@y
+GRANT USAGE ON *.* TO 'x'@'y'
+show binlog events;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	4	Format_desc	1	98	Server ver: VERSION, Binlog ver: 4
+master-bin.000001	98	Query	1	185	drop database if exists d1
+master-bin.000001	185	Query	1	264	create database d1
+master-bin.000001	264	Query	1	362	use `d1`; create table t (s1 int) engine=innodb
+master-bin.000001	362	Query	1	428	use `d1`; BEGIN
+master-bin.000001	428	Query	1	85	use `d1`; insert into t values (1)
+master-bin.000001	513	Xid	1	540	COMMIT /* xid=11 */
+master-bin.000001	540	Query	1	625	use `d1`; grant select on t to x@y
+master-bin.000001	625	Query	1	691	use `d1`; BEGIN
+master-bin.000001	691	Query	1	85	use `d1`; insert into t values (2)
+master-bin.000001	776	Xid	1	803	COMMIT /* xid=17 */
+master-bin.000001	803	Query	1	891	use `d1`; revoke select on t from x@y
+drop user x@y;
+drop database d1;


