List:Internals« Previous MessageNext Message »
From:guilhem Date:October 17 2005 10:52am
Subject:bk commit into 5.0 tree (guilhem:1.2044) BUG#4544
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of guilhem. When guilhem does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2044 05/10/17 10:52:34 guilhem@stripped +3 -0
  Fix for BUG#4544 "read_only also affects temporary tables":
  the READ_ONLY global variable now allows statements which are to update only temporary
tables
  (note: if a statement, after parse stage, looks like it will update a non-temp table, it
will be rejected,
  even if at execution it would have turned out that 0 rows would be updated; for example
  UPDATE my_non_tem_table SET a=1 WHERE 1 = 0; will be rejected).

  mysql-test/t/read_only.test
    1.1 05/10/17 10:52:22 guilhem@stripped +103 -0
    test for READ_ONLY (there was none!) and for the new behaviour of READ_ONLY

  mysql-test/r/read_only.result
    1.1 05/10/17 10:52:22 guilhem@stripped +41 -0
    result for new test

  sql/sql_parse.cc
    1.507 05/10/17 10:52:22 guilhem@stripped +37 -10
    The READ_ONLY global variable now allows statements which are to update only temporary
tables
    (note: if a statement, after parse stage, looks like it will update a non-temp table,
it will be rejected,
    even if at execution it would have turned out that 0 rows would be updated; for
example
    UPDATE my_non_tem_table SET a=1 WHERE 1 = 0; will be rejected).

  mysql-test/t/read_only.test
    1.0 05/10/17 10:52:22 guilhem@stripped +0 -0
    BitKeeper file /home/mysql_src/mysql-5.0/mysql-test/t/read_only.test

  mysql-test/r/read_only.result
    1.0 05/10/17 10:52:22 guilhem@stripped +0 -0
    BitKeeper file /home/mysql_src/mysql-5.0/mysql-test/r/read_only.result

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	guilhem
# Host:	gbichot3.local
# Root:	/home/mysql_src/mysql-5.0

--- 1.506/sql/sql_parse.cc	2005-10-13 11:12:07 +02:00
+++ 1.507/sql/sql_parse.cc	2005-10-17 10:52:22 +02:00
@@ -194,6 +194,18 @@
 #endif
 
 
+static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
+{
+  for (TABLE_LIST *table= tables; table; table= table->next_global)
+  {
+    DBUG_ASSERT(table->db && table->table_name);
+    if (table->updating &&
+        !find_temporary_table(thd, table->db, table->table_name))
+      return 1;
+  }
+  return 0;
+}
+
 static HASH hash_user_connections;
 
 static int get_or_create_user_conn(THD *thd, const char *user,
@@ -2363,7 +2375,7 @@
     mysql_reset_errors(thd, 0);
 
 #ifdef HAVE_REPLICATION
-  if (thd->slave_thread)
+  if (unlikely(thd->slave_thread))
   {
     /*
       Check if statment should be skipped because of slave filtering
@@ -2402,16 +2414,20 @@
     }
 #endif
   }
+  else
 #endif /* HAVE_REPLICATION */
 
   /*
-    When option readonly is set deny operations which change tables.
-    Except for the replication thread and the 'super' users.
+    When option readonly is set deny operations which change non-temporary
+    tables. Except for the replication thread and the 'super' users.
   */
   if (opt_readonly &&
-      !(thd->slave_thread ||
-        (thd->security_ctx->master_access & SUPER_ACL)) &&
-      uc_update_queries[lex->sql_command])
+      !(thd->security_ctx->master_access & SUPER_ACL) &&
+      uc_update_queries[lex->sql_command] &&
+      !((lex->sql_command == SQLCOM_CREATE_TABLE) &&
+        (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE)) &&
+      ((lex->sql_command != SQLCOM_UPDATE_MULTI) &&
+       some_non_temp_table_to_be_updated(thd, all_tables)))
   {
     my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
     DBUG_RETURN(-1);
@@ -3210,13 +3226,24 @@
 
 #ifdef HAVE_REPLICATION
     /* Check slave filtering rules */
-    if (thd->slave_thread && all_tables_not_ok(thd, all_tables))
+    if (unlikely(thd->slave_thread))
     {
-      /* we warn the slave SQL thread */
-      my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
-      break;
+      if (all_tables_not_ok(thd, all_tables))
+      {
+        /* we warn the slave SQL thread */
+        my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
+        break;
+      }
     }
+    else
 #endif /* HAVE_REPLICATION */
+    if (opt_readonly &&
+        !(thd->security_ctx->master_access & SUPER_ACL) &&
+        some_non_temp_table_to_be_updated(thd, all_tables))
+    {
+      my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
+      break;
+    }
 
     res= mysql_multi_update(thd, all_tables,
                             &select_lex->item_list,
--- New file ---
+++ mysql-test/r/read_only.result	05/10/17 10:52:22
DROP TABLE IF EXISTS t1,t2,t3;
grant CREATE, SELECT, DROP on *.* to test@localhost;
set global read_only=0;
create table t1 (a int);
insert into t1 values(1);
create table t2 select * from t1;
set global read_only=1;
create table t3 (a int);
drop table t3;
select @@global.read_only;
@@global.read_only
1
create table t3 (a int);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute
this statement
insert into t1 values(1);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute
this statement
update t1,t2 set t1.a=t2.a+1 where t1.a=t2.a;
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute
this statement
delete t1,t2 from t1,t2 where t1.a=t2.a;
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute
this statement
create temporary table t3 (a int);
create temporary table t4 (a int) select * from t3;
insert into t3 values(1);
insert into t4 select * from t3;
update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a;
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute
this statement
update t1,t3 set t3.a=t1.a+1 where t1.a=t3.a;
update t4,t3 set t4.a=t3.a+1 where t4.a=t3.a;
delete t1 from t1,t3 where t1.a=t3.a;
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute
this statement
delete t3 from t1,t3 where t1.a=t3.a;
delete t4 from t3,t4 where t4.a=t3.a;
create temporary table t1 (a int);
insert into t1 values(1);
update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a;
delete t1 from t1,t3 where t1.a=t3.a;
drop table t1;
insert into t1 values(1);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute
this statement
drop table t1,t2;
drop user test@localhost;

--- New file ---
+++ mysql-test/t/read_only.test	05/10/17 10:52:22
# Test of the READ_ONLY global variable:
# check that it blocks updates unless they are only on temporary tables.

--disable_warnings
DROP TABLE IF EXISTS t1,t2,t3;
--enable_warnings

# READ_ONLY does nothing to SUPER users
# so we use a non-SUPER one:

grant CREATE, SELECT, DROP on *.* to test@localhost;

connect (con1,localhost,test,,test);

connection default;

set global read_only=0;

connection con1;

create table t1 (a int);

insert into t1 values(1);

create table t2 select * from t1;

connection default;

set global read_only=1;

# We check that SUPER can:

create table t3 (a int);
drop table t3;

connection con1;

select @@global.read_only;

--error 1290
create table t3 (a int);

--error 1290
insert into t1 values(1);

# if a statement, after parse stage, looks like it will update a
# non-temp table, it will be rejected, even if at execution it would
# have turned out that 0 rows would be updated
--error 1290
update t1 set a=1 where 1=0;

# multi-update is special (see sql_parse.cc) so we test it
--error 1290
update t1,t2 set t1.a=t2.a+1 where t1.a=t2.a;

# check multi-delete to be sure
--error 1290
delete t1,t2 from t1,t2 where t1.a=t2.a;

# With temp tables updates should be accepted:

create temporary table t3 (a int);

create temporary table t4 (a int) select * from t3;

insert into t3 values(1);

insert into t4 select * from t3;

# a non-temp table updated:
--error 1290
update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a;

# no non-temp table updated (just swapped):
update t1,t3 set t3.a=t1.a+1 where t1.a=t3.a;

update t4,t3 set t4.a=t3.a+1 where t4.a=t3.a;

--error 1290
delete t1 from t1,t3 where t1.a=t3.a;

delete t3 from t1,t3 where t1.a=t3.a;

delete t4 from t3,t4 where t4.a=t3.a;

# and even homonymous ones

create temporary table t1 (a int);

insert into t1 values(1);

update t1,t3 set t1.a=t3.a+1 where t1.a=t3.a;

delete t1 from t1,t3 where t1.a=t3.a;

drop table t1;

--error 1290
insert into t1 values(1);

connection default;
drop table t1,t2;
drop user test@localhost;

Thread
bk commit into 5.0 tree (guilhem:1.2044) BUG#4544guilhem17 Oct