mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge gbichot@bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/home/mysql_src/mysql-5.0 sql/sql_parse.cc: Auto merged
This commit is contained in:
41
mysql-test/r/read_only.result
Normal file
41
mysql-test/r/read_only.result
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
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
mysql-test/t/read_only.test
Normal file
103
mysql-test/t/read_only.test
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
# 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;
|
@ -194,6 +194,18 @@ inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
|
|||||||
#endif
|
#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 HASH hash_user_connections;
|
||||||
|
|
||||||
static int get_or_create_user_conn(THD *thd, const char *user,
|
static int get_or_create_user_conn(THD *thd, const char *user,
|
||||||
@ -2363,7 +2375,7 @@ mysql_execute_command(THD *thd)
|
|||||||
mysql_reset_errors(thd, 0);
|
mysql_reset_errors(thd, 0);
|
||||||
|
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
if (thd->slave_thread)
|
if (unlikely(thd->slave_thread))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Check if statment should be skipped because of slave filtering
|
Check if statment should be skipped because of slave filtering
|
||||||
@ -2402,16 +2414,20 @@ mysql_execute_command(THD *thd)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
else
|
||||||
#endif /* HAVE_REPLICATION */
|
#endif /* HAVE_REPLICATION */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
When option readonly is set deny operations which change tables.
|
When option readonly is set deny operations which change non-temporary
|
||||||
Except for the replication thread and the 'super' users.
|
tables. Except for the replication thread and the 'super' users.
|
||||||
*/
|
*/
|
||||||
if (opt_readonly &&
|
if (opt_readonly &&
|
||||||
!(thd->slave_thread ||
|
!(thd->security_ctx->master_access & SUPER_ACL) &&
|
||||||
(thd->security_ctx->master_access & SUPER_ACL)) &&
|
uc_update_queries[lex->sql_command] &&
|
||||||
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");
|
my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
@ -3210,13 +3226,24 @@ end_with_restore_list:
|
|||||||
|
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
/* Check slave filtering rules */
|
/* 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 */
|
if (all_tables_not_ok(thd, all_tables))
|
||||||
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
|
{
|
||||||
|
/* 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;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_REPLICATION */
|
|
||||||
|
|
||||||
res= mysql_multi_update(thd, all_tables,
|
res= mysql_multi_update(thd, all_tables,
|
||||||
&select_lex->item_list,
|
&select_lex->item_list,
|
||||||
|
Reference in New Issue
Block a user