bugfix: multi-update checked privileges on views incorrectly
it always required UPDATE privilege on views, not being able to detect when a views was not actually updated in multi-update. fix: instead of marking all tables as "updating" by default, only set "updating" on tables that will actually be updated by multi-update. And mark the view "updating" if any of the view's tables is.
This commit is contained in:
parent
822071ca5b
commit
5057d46375
@ -173,11 +173,14 @@ create table mysqltest.t1 (a int, b int, primary key(a));
|
|||||||
insert into mysqltest.t1 values (10,2), (20,3), (30,4), (40,5), (50,10);
|
insert into mysqltest.t1 values (10,2), (20,3), (30,4), (40,5), (50,10);
|
||||||
create table mysqltest.t2 (x int);
|
create table mysqltest.t2 (x int);
|
||||||
insert into mysqltest.t2 values (3), (4), (5), (6);
|
insert into mysqltest.t2 values (3), (4), (5), (6);
|
||||||
|
create table mysqltest.t3 (x int);
|
||||||
|
insert into mysqltest.t3 values (3), (4), (5), (6);
|
||||||
create view mysqltest.v1 (a,c) as select a, b+1 from mysqltest.t1;
|
create view mysqltest.v1 (a,c) as select a, b+1 from mysqltest.t1;
|
||||||
create view mysqltest.v2 (a,c) as select a, b from mysqltest.t1;
|
create view mysqltest.v2 (a,c) as select a, b from mysqltest.t1;
|
||||||
create view mysqltest.v3 (a,c) as select a, b+1 from mysqltest.t1;
|
create view mysqltest.v3 (a,c) as select a, b+1 from mysqltest.t1;
|
||||||
grant update (a) on mysqltest.v2 to mysqltest_1@localhost;
|
grant update (a) on mysqltest.v2 to mysqltest_1@localhost;
|
||||||
grant update on mysqltest.v1 to mysqltest_1@localhost;
|
grant update on mysqltest.v1 to mysqltest_1@localhost;
|
||||||
|
grant update on mysqltest.t3 to mysqltest_1@localhost;
|
||||||
grant select on mysqltest.* to mysqltest_1@localhost;
|
grant select on mysqltest.* to mysqltest_1@localhost;
|
||||||
use mysqltest;
|
use mysqltest;
|
||||||
update t2,v1 set v1.a=v1.a+v1.c where t2.x=v1.c;
|
update t2,v1 set v1.a=v1.a+v1.c where t2.x=v1.c;
|
||||||
@ -212,6 +215,7 @@ a b
|
|||||||
48 4
|
48 4
|
||||||
62 5
|
62 5
|
||||||
71 10
|
71 10
|
||||||
|
update t3,v3 set t3.x=t3.x+v3.c where t3.x=v3.c;
|
||||||
update t2,v2 set v2.c=v2.a+v2.c where t2.x=v2.c;
|
update t2,v2 set v2.c=v2.a+v2.c where t2.x=v2.c;
|
||||||
ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for column 'c' in table 'v2'
|
ERROR 42000: UPDATE command denied to user 'mysqltest_1'@'localhost' for column 'c' in table 'v2'
|
||||||
update v2 set c=a+c;
|
update v2 set c=a+c;
|
||||||
|
@ -240,12 +240,15 @@ create table mysqltest.t1 (a int, b int, primary key(a));
|
|||||||
insert into mysqltest.t1 values (10,2), (20,3), (30,4), (40,5), (50,10);
|
insert into mysqltest.t1 values (10,2), (20,3), (30,4), (40,5), (50,10);
|
||||||
create table mysqltest.t2 (x int);
|
create table mysqltest.t2 (x int);
|
||||||
insert into mysqltest.t2 values (3), (4), (5), (6);
|
insert into mysqltest.t2 values (3), (4), (5), (6);
|
||||||
|
create table mysqltest.t3 (x int);
|
||||||
|
insert into mysqltest.t3 values (3), (4), (5), (6);
|
||||||
create view mysqltest.v1 (a,c) as select a, b+1 from mysqltest.t1;
|
create view mysqltest.v1 (a,c) as select a, b+1 from mysqltest.t1;
|
||||||
create view mysqltest.v2 (a,c) as select a, b from mysqltest.t1;
|
create view mysqltest.v2 (a,c) as select a, b from mysqltest.t1;
|
||||||
create view mysqltest.v3 (a,c) as select a, b+1 from mysqltest.t1;
|
create view mysqltest.v3 (a,c) as select a, b+1 from mysqltest.t1;
|
||||||
|
|
||||||
grant update (a) on mysqltest.v2 to mysqltest_1@localhost;
|
grant update (a) on mysqltest.v2 to mysqltest_1@localhost;
|
||||||
grant update on mysqltest.v1 to mysqltest_1@localhost;
|
grant update on mysqltest.v1 to mysqltest_1@localhost;
|
||||||
|
grant update on mysqltest.t3 to mysqltest_1@localhost;
|
||||||
grant select on mysqltest.* to mysqltest_1@localhost;
|
grant select on mysqltest.* to mysqltest_1@localhost;
|
||||||
|
|
||||||
connection user1;
|
connection user1;
|
||||||
@ -260,6 +263,8 @@ update t2,v2 set v2.a=v2.a+v2.c where t2.x=v2.c;
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
update v2 set a=a+c;
|
update v2 set a=a+c;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
|
# update a table, select only on view
|
||||||
|
update t3,v3 set t3.x=t3.x+v3.c where t3.x=v3.c;
|
||||||
# no rights on column
|
# no rights on column
|
||||||
--error ER_COLUMNACCESS_DENIED_ERROR
|
--error ER_COLUMNACCESS_DENIED_ERROR
|
||||||
update t2,v2 set v2.c=v2.a+v2.c where t2.x=v2.c;
|
update t2,v2 set v2.c=v2.a+v2.c where t2.x=v2.c;
|
||||||
|
@ -589,7 +589,7 @@ public:
|
|||||||
enum_mdl_type mdl_type= MDL_SHARED_READ,
|
enum_mdl_type mdl_type= MDL_SHARED_READ,
|
||||||
List<Index_hint> *hints= 0,
|
List<Index_hint> *hints= 0,
|
||||||
LEX_STRING *option= 0);
|
LEX_STRING *option= 0);
|
||||||
virtual void set_lock_for_tables(thr_lock_type lock_type) {}
|
virtual void set_lock_for_tables(thr_lock_type lock_type, bool for_update) {}
|
||||||
|
|
||||||
friend class st_select_lex_unit;
|
friend class st_select_lex_unit;
|
||||||
friend bool mysql_new_select(LEX *lex, bool move_down);
|
friend bool mysql_new_select(LEX *lex, bool move_down);
|
||||||
@ -960,7 +960,7 @@ public:
|
|||||||
TABLE_LIST *convert_right_join();
|
TABLE_LIST *convert_right_join();
|
||||||
List<Item>* get_item_list();
|
List<Item>* get_item_list();
|
||||||
ulong get_table_join_options();
|
ulong get_table_join_options();
|
||||||
void set_lock_for_tables(thr_lock_type lock_type);
|
void set_lock_for_tables(thr_lock_type lock_type, bool for_update);
|
||||||
inline void init_order()
|
inline void init_order()
|
||||||
{
|
{
|
||||||
order_list.elements= 0;
|
order_list.elements= 0;
|
||||||
|
@ -2065,9 +2065,6 @@ mysql_execute_command(THD *thd)
|
|||||||
reset_one_shot_variables(thd);
|
reset_one_shot_variables(thd);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (table=all_tables; table; table=table->next_global)
|
|
||||||
table->updating= TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -6541,9 +6538,8 @@ TABLE_LIST *st_select_lex::convert_right_join()
|
|||||||
query
|
query
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
|
void st_select_lex::set_lock_for_tables(thr_lock_type lock_type, bool for_update)
|
||||||
{
|
{
|
||||||
bool for_update= lock_type >= TL_READ_NO_INSERT;
|
|
||||||
DBUG_ENTER("set_lock_for_tables");
|
DBUG_ENTER("set_lock_for_tables");
|
||||||
DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type,
|
DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type,
|
||||||
for_update));
|
for_update));
|
||||||
|
@ -1305,6 +1305,9 @@ int mysql_multi_update_prepare(THD *thd)
|
|||||||
If table will be updated we should not downgrade lock for it and
|
If table will be updated we should not downgrade lock for it and
|
||||||
leave it as is.
|
leave it as is.
|
||||||
*/
|
*/
|
||||||
|
tl->updating= 1;
|
||||||
|
if (tl->belong_to_view)
|
||||||
|
tl->belong_to_view->updating= 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1323,7 +1326,6 @@ int mysql_multi_update_prepare(THD *thd)
|
|||||||
tl->lock_type= read_lock_type_for_table(thd, lex, tl);
|
tl->lock_type= read_lock_type_for_table(thd, lex, tl);
|
||||||
else
|
else
|
||||||
tl->set_lock_type(thd, read_lock_type_for_table(thd, lex, tl));
|
tl->set_lock_type(thd, read_lock_type_for_table(thd, lex, tl));
|
||||||
tl->updating= 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (tl= table_list; tl; tl= tl->next_local)
|
for (tl= table_list; tl; tl= tl->next_local)
|
||||||
|
@ -7676,14 +7676,14 @@ select_lock_type:
|
|||||||
| FOR_SYM UPDATE_SYM
|
| FOR_SYM UPDATE_SYM
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->current_select->set_lock_for_tables(TL_WRITE);
|
lex->current_select->set_lock_for_tables(TL_WRITE, false);
|
||||||
lex->safe_to_cache_query=0;
|
lex->safe_to_cache_query=0;
|
||||||
}
|
}
|
||||||
| LOCK_SYM IN_SYM SHARE_SYM MODE_SYM
|
| LOCK_SYM IN_SYM SHARE_SYM MODE_SYM
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->current_select->
|
lex->current_select->
|
||||||
set_lock_for_tables(TL_READ_WITH_SHARED_LOCKS);
|
set_lock_for_tables(TL_READ_WITH_SHARED_LOCKS, false);
|
||||||
lex->safe_to_cache_query=0;
|
lex->safe_to_cache_query=0;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -10966,7 +10966,7 @@ insert:
|
|||||||
insert_lock_option
|
insert_lock_option
|
||||||
opt_ignore insert2
|
opt_ignore insert2
|
||||||
{
|
{
|
||||||
Select->set_lock_for_tables($3);
|
Select->set_lock_for_tables($3, true);
|
||||||
Lex->current_select= &Lex->select_lex;
|
Lex->current_select= &Lex->select_lex;
|
||||||
}
|
}
|
||||||
insert_field_spec opt_insert_update
|
insert_field_spec opt_insert_update
|
||||||
@ -10983,7 +10983,7 @@ replace:
|
|||||||
}
|
}
|
||||||
replace_lock_option insert2
|
replace_lock_option insert2
|
||||||
{
|
{
|
||||||
Select->set_lock_for_tables($3);
|
Select->set_lock_for_tables($3, true);
|
||||||
Lex->current_select= &Lex->select_lex;
|
Lex->current_select= &Lex->select_lex;
|
||||||
}
|
}
|
||||||
insert_field_spec
|
insert_field_spec
|
||||||
@ -11174,7 +11174,7 @@ update:
|
|||||||
be too pessimistic. We will decrease lock level if possible in
|
be too pessimistic. We will decrease lock level if possible in
|
||||||
mysql_multi_update().
|
mysql_multi_update().
|
||||||
*/
|
*/
|
||||||
slex->set_lock_for_tables($3);
|
slex->set_lock_for_tables($3, slex->table_list.elements == 1);
|
||||||
}
|
}
|
||||||
where_clause opt_order_clause delete_limit_clause {}
|
where_clause opt_order_clause delete_limit_clause {}
|
||||||
;
|
;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user