Commit 14cb1abb authored by unknown's avatar unknown
Browse files

sql_parse.cc:

  SCCS merged


sql/sql_parse.cc:
  SCCS merged
parents 71898b3e ff34d071
Loading
Loading
Loading
Loading
+41 −0
Original line number Diff line number Diff line
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;
+103 −0
Original line number Diff line number Diff line
# 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;
+37 −10
Original line number Diff line number Diff line
@@ -194,6 +194,18 @@ inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
#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,
@@ -2365,7 +2377,7 @@ mysql_execute_command(THD *thd)
    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
@@ -2404,16 +2416,20 @@ mysql_execute_command(THD *thd)
    }
#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);
@@ -3212,13 +3228,24 @@ mysql_execute_command(THD *thd)

#ifdef HAVE_REPLICATION
    /* Check slave filtering rules */
    if (thd->slave_thread && all_tables_not_ok(thd, all_tables))
    if (unlikely(thd->slave_thread))
    {
      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,