Loading mysql-test/r/sp-error.result +40 −0 Original line number Diff line number Diff line Loading @@ -1057,6 +1057,46 @@ Db Name Type Definer Modified Created Security_type Comment mysqltest2 p1 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER drop database mysqltest2; use test; drop function if exists bug11555_1; drop function if exists bug11555_2; drop view if exists v1, v2, v3, v4; create function bug11555_1() returns int return (select max(i) from t1); create function bug11555_2() returns int return bug11555_1(); create view v1 as select bug11555_1(); ERROR 42S02: Table 'test.t1' doesn't exist create view v2 as select bug11555_2(); ERROR 42S02: Table 'test.t1' doesn't exist create table t1 (i int); create view v1 as select bug11555_1(); create view v2 as select bug11555_2(); create view v3 as select * from v1; drop table t1; select * from v1; ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them select * from v2; ERROR HY000: View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them select * from v3; ERROR HY000: View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them create view v4 as select * from v1; ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them drop view v1, v2, v3; drop function bug11555_1; drop function bug11555_2; create table t1 (i int); create table t2 (i int); create trigger t1_ai after insert on t1 for each row insert into t2 values (new.i); create view v1 as select * from t1; drop table t2; insert into v1 values (1); ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them drop trigger t1_ai; create function bug11555_1() returns int return (select max(i) from t2); create trigger t1_ai after insert on t1 for each row set @a:=bug11555_1(); insert into v1 values (2); ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them drop function bug11555_1; drop table t1; drop view v1; DROP FUNCTION IF EXISTS bug13012| CREATE FUNCTION bug13012() RETURNS INT BEGIN Loading mysql-test/r/view.result +3 −3 Original line number Diff line number Diff line Loading @@ -1933,11 +1933,11 @@ create function f1 () returns int return (select max(col1) from t1); DROP TABLE t1; CHECK TABLE v1, v2, v3, v4, v5, v6; Table Op Msg_type Msg_text test.v1 check error Table 'test.t1' doesn't exist test.v1 check error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them test.v2 check status OK test.v3 check error Table 'test.t1' doesn't exist test.v3 check error View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them test.v4 check status OK test.v5 check error Table 'test.t1' doesn't exist test.v5 check error View 'test.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them test.v6 check status OK drop function f1; drop function f2; Loading mysql-test/t/sp-error.test +61 −0 Original line number Diff line number Diff line Loading @@ -1556,6 +1556,67 @@ drop procedure bug13012_1| drop function bug13012_2| delimiter ;| # BUG#11555 "Stored procedures: current SP tables locking make # impossible view security". We should not expose names of tables # which are implicitly used by view (via stored routines/triggers). # # Note that SQL standard assumes that you simply won't be able drop table # and leave some objects (routines/views/triggers) which were depending on # it. Such objects should be dropped in advance (by default) or will be # dropped simultaneously with table (DROP TABLE with CASCADE clause). # So these tests probably should go away once we will implement standard # behavior. --disable_warnings drop function if exists bug11555_1; drop function if exists bug11555_2; drop view if exists v1, v2, v3, v4; --enable_warnings create function bug11555_1() returns int return (select max(i) from t1); create function bug11555_2() returns int return bug11555_1(); # It is OK to report name of implicitly used table which is missing # when we create view. --error ER_NO_SUCH_TABLE create view v1 as select bug11555_1(); --error ER_NO_SUCH_TABLE create view v2 as select bug11555_2(); # But we should hide name of missing implicitly used table when we use view create table t1 (i int); create view v1 as select bug11555_1(); create view v2 as select bug11555_2(); create view v3 as select * from v1; drop table t1; --error ER_VIEW_INVALID select * from v1; --error ER_VIEW_INVALID select * from v2; --error ER_VIEW_INVALID select * from v3; # Note that creation of view which depends on broken view is yet # another form of view usage. --error ER_VIEW_INVALID create view v4 as select * from v1; drop view v1, v2, v3; # We also should hide details about broken triggers which are # invoked for view. drop function bug11555_1; drop function bug11555_2; create table t1 (i int); create table t2 (i int); create trigger t1_ai after insert on t1 for each row insert into t2 values (new.i); create view v1 as select * from t1; drop table t2; --error ER_VIEW_INVALID insert into v1 values (1); drop trigger t1_ai; create function bug11555_1() returns int return (select max(i) from t2); create trigger t1_ai after insert on t1 for each row set @a:=bug11555_1(); --error ER_VIEW_INVALID insert into v1 values (2); drop function bug11555_1; drop table t1; drop view v1; # BUG#NNNN: New bug synopsis # #--disable_warnings Loading mysql-test/t/view.test +0 −1 Original line number Diff line number Diff line Loading @@ -1744,7 +1744,6 @@ drop function f1; CHECK TABLE v1, v2, v3, v4, v5, v6; create function f1 () returns int return (select max(col1) from t1); DROP TABLE t1; # following will show underlying table until BUG#11555 fix CHECK TABLE v1, v2, v3, v4, v5, v6; drop function f1; drop function f2; Loading sql/sp.cc +53 −32 Original line number Diff line number Diff line Loading @@ -1199,6 +1199,12 @@ struct Sroutine_hash_entry for LEX::sroutine/sroutine_list and sp_head::m_sroutines. */ Sroutine_hash_entry *next; /* Uppermost view which directly or indirectly uses this routine. 0 if routine is not used in view. Note that it also can be 0 if statement uses routine both via view and directly. */ TABLE_LIST *belong_to_view; }; Loading Loading @@ -1253,9 +1259,11 @@ void sp_get_prelocking_info(THD *thd, bool *need_prelocking, SYNOPSIS add_used_routine() lex - LEX representing statement arena - arena in which memory for new element will be allocated key - key for the hash representing set lex LEX representing statement arena Arena in which memory for new element will be allocated key Key for the hash representing set belong_to_view Uppermost view which uses this routine (0 if routine is not used by view) NOTES Will also add element to end of 'LEX::sroutines_list' list. Loading @@ -1278,7 +1286,8 @@ void sp_get_prelocking_info(THD *thd, bool *need_prelocking, */ static bool add_used_routine(LEX *lex, Query_arena *arena, const LEX_STRING *key) const LEX_STRING *key, TABLE_LIST *belong_to_view) { if (!hash_search(&lex->sroutines, (byte *)key->str, key->length)) { Loading @@ -1292,6 +1301,7 @@ static bool add_used_routine(LEX *lex, Query_arena *arena, memcpy(rn->key.str, key->str, key->length); my_hash_insert(&lex->sroutines, (byte *)rn); lex->sroutines_list.link_in_list((byte *)rn, (byte **)&rn->next); rn->belong_to_view= belong_to_view; return TRUE; } return FALSE; Loading Loading @@ -1322,7 +1332,7 @@ void sp_add_used_routine(LEX *lex, Query_arena *arena, sp_name *rt, char rt_type) { rt->set_routine_type(rt_type); (void)add_used_routine(lex, arena, &rt->m_sroutines_key); (void)add_used_routine(lex, arena, &rt->m_sroutines_key, 0); lex->sroutines_list_own_last= lex->sroutines_list.next; lex->sroutines_list_own_elements= lex->sroutines_list.elements; } Loading Loading @@ -1392,20 +1402,23 @@ void sp_update_sp_used_routines(HASH *dst, HASH *src) SYNOPSIS sp_update_stmt_used_routines() thd - thread context lex - LEX representing statement src - hash representing set from which routines will be added thd Thread context lex LEX representing statement src Hash representing set from which routines will be added belong_to_view Uppermost view which uses these routines, 0 if none NOTE It will also add elements to end of 'LEX::sroutines_list' list. */ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, HASH *src) static void sp_update_stmt_used_routines(THD *thd, LEX *lex, HASH *src, TABLE_LIST *belong_to_view) { for (uint i=0 ; i < src->records ; i++) { Sroutine_hash_entry *rt= (Sroutine_hash_entry *)hash_element(src, i); (void)add_used_routine(lex, thd->stmt_arena, &rt->key); (void)add_used_routine(lex, thd->stmt_arena, &rt->key, belong_to_view); } } Loading @@ -1419,16 +1432,18 @@ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, HASH *src) thd Thread context lex LEX representing statement src List representing set from which routines will be added belong_to_view Uppermost view which uses these routines, 0 if none NOTE It will also add elements to end of 'LEX::sroutines_list' list. */ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src) static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src, TABLE_LIST *belong_to_view) { for (Sroutine_hash_entry *rt= (Sroutine_hash_entry *)src->first; rt; rt= rt->next) (void)add_used_routine(lex, thd->stmt_arena, &rt->key); (void)add_used_routine(lex, thd->stmt_arena, &rt->key, belong_to_view); } Loading Loading @@ -1533,9 +1548,11 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex, { if (!(first && first_no_prelock)) { sp_update_stmt_used_routines(thd, lex, &sp->m_sroutines); sp_update_stmt_used_routines(thd, lex, &sp->m_sroutines, rt->belong_to_view); tabschnd|= sp->add_used_tables_to_table_list(thd, &lex->query_tables_last); sp->add_used_tables_to_table_list(thd, &lex->query_tables_last, rt->belong_to_view); } } first= FALSE; Loading Loading @@ -1581,9 +1598,9 @@ sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock, SYNOPSIS sp_cache_routines_and_add_tables_for_view() thd - thread context lex - LEX representing statement aux_lex - LEX representing view thd Thread context lex LEX representing statement view Table list element representing view RETURN VALUE 0 - success Loading @@ -1591,11 +1608,12 @@ sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock, */ int sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex) sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, TABLE_LIST *view) { Sroutine_hash_entry **last_cached_routine_ptr= (Sroutine_hash_entry **)lex->sroutines_list.next; sp_update_stmt_used_routines(thd, lex, &aux_lex->sroutines_list); sp_update_stmt_used_routines(thd, lex, &view->view->sroutines_list, view->top_table()); return sp_cache_routines_and_add_tables_aux(thd, lex, *last_cached_routine_ptr, FALSE, NULL); Loading @@ -1609,9 +1627,9 @@ sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex) SYNOPSIS sp_cache_routines_and_add_tables_for_triggers() thd - thread context lex - LEX respresenting statement triggers - triggers of the table thd thread context lex LEX respresenting statement table Table list element for table with trigger RETURN VALUE 0 - success Loading @@ -1620,11 +1638,12 @@ sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex) int sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex, Table_triggers_list *triggers) TABLE_LIST *table) { int ret= 0; if (add_used_routine(lex, thd->stmt_arena, &triggers->sroutines_key)) Table_triggers_list *triggers= table->table->triggers; if (add_used_routine(lex, thd->stmt_arena, &triggers->sroutines_key, table->belong_to_view)) { Sroutine_hash_entry **last_cached_routine_ptr= (Sroutine_hash_entry **)lex->sroutines_list.next; Loading @@ -1634,10 +1653,12 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex, { if (triggers->bodies[i][j]) { (void)triggers->bodies[i][j]->add_used_tables_to_table_list(thd, &lex->query_tables_last); (void)triggers->bodies[i][j]-> add_used_tables_to_table_list(thd, &lex->query_tables_last, table->belong_to_view); sp_update_stmt_used_routines(thd, lex, &triggers->bodies[i][j]->m_sroutines); &triggers->bodies[i][j]->m_sroutines, table->belong_to_view); } } } Loading Loading
mysql-test/r/sp-error.result +40 −0 Original line number Diff line number Diff line Loading @@ -1057,6 +1057,46 @@ Db Name Type Definer Modified Created Security_type Comment mysqltest2 p1 PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER drop database mysqltest2; use test; drop function if exists bug11555_1; drop function if exists bug11555_2; drop view if exists v1, v2, v3, v4; create function bug11555_1() returns int return (select max(i) from t1); create function bug11555_2() returns int return bug11555_1(); create view v1 as select bug11555_1(); ERROR 42S02: Table 'test.t1' doesn't exist create view v2 as select bug11555_2(); ERROR 42S02: Table 'test.t1' doesn't exist create table t1 (i int); create view v1 as select bug11555_1(); create view v2 as select bug11555_2(); create view v3 as select * from v1; drop table t1; select * from v1; ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them select * from v2; ERROR HY000: View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them select * from v3; ERROR HY000: View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them create view v4 as select * from v1; ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them drop view v1, v2, v3; drop function bug11555_1; drop function bug11555_2; create table t1 (i int); create table t2 (i int); create trigger t1_ai after insert on t1 for each row insert into t2 values (new.i); create view v1 as select * from t1; drop table t2; insert into v1 values (1); ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them drop trigger t1_ai; create function bug11555_1() returns int return (select max(i) from t2); create trigger t1_ai after insert on t1 for each row set @a:=bug11555_1(); insert into v1 values (2); ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them drop function bug11555_1; drop table t1; drop view v1; DROP FUNCTION IF EXISTS bug13012| CREATE FUNCTION bug13012() RETURNS INT BEGIN Loading
mysql-test/r/view.result +3 −3 Original line number Diff line number Diff line Loading @@ -1933,11 +1933,11 @@ create function f1 () returns int return (select max(col1) from t1); DROP TABLE t1; CHECK TABLE v1, v2, v3, v4, v5, v6; Table Op Msg_type Msg_text test.v1 check error Table 'test.t1' doesn't exist test.v1 check error View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them test.v2 check status OK test.v3 check error Table 'test.t1' doesn't exist test.v3 check error View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them test.v4 check status OK test.v5 check error Table 'test.t1' doesn't exist test.v5 check error View 'test.v5' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them test.v6 check status OK drop function f1; drop function f2; Loading
mysql-test/t/sp-error.test +61 −0 Original line number Diff line number Diff line Loading @@ -1556,6 +1556,67 @@ drop procedure bug13012_1| drop function bug13012_2| delimiter ;| # BUG#11555 "Stored procedures: current SP tables locking make # impossible view security". We should not expose names of tables # which are implicitly used by view (via stored routines/triggers). # # Note that SQL standard assumes that you simply won't be able drop table # and leave some objects (routines/views/triggers) which were depending on # it. Such objects should be dropped in advance (by default) or will be # dropped simultaneously with table (DROP TABLE with CASCADE clause). # So these tests probably should go away once we will implement standard # behavior. --disable_warnings drop function if exists bug11555_1; drop function if exists bug11555_2; drop view if exists v1, v2, v3, v4; --enable_warnings create function bug11555_1() returns int return (select max(i) from t1); create function bug11555_2() returns int return bug11555_1(); # It is OK to report name of implicitly used table which is missing # when we create view. --error ER_NO_SUCH_TABLE create view v1 as select bug11555_1(); --error ER_NO_SUCH_TABLE create view v2 as select bug11555_2(); # But we should hide name of missing implicitly used table when we use view create table t1 (i int); create view v1 as select bug11555_1(); create view v2 as select bug11555_2(); create view v3 as select * from v1; drop table t1; --error ER_VIEW_INVALID select * from v1; --error ER_VIEW_INVALID select * from v2; --error ER_VIEW_INVALID select * from v3; # Note that creation of view which depends on broken view is yet # another form of view usage. --error ER_VIEW_INVALID create view v4 as select * from v1; drop view v1, v2, v3; # We also should hide details about broken triggers which are # invoked for view. drop function bug11555_1; drop function bug11555_2; create table t1 (i int); create table t2 (i int); create trigger t1_ai after insert on t1 for each row insert into t2 values (new.i); create view v1 as select * from t1; drop table t2; --error ER_VIEW_INVALID insert into v1 values (1); drop trigger t1_ai; create function bug11555_1() returns int return (select max(i) from t2); create trigger t1_ai after insert on t1 for each row set @a:=bug11555_1(); --error ER_VIEW_INVALID insert into v1 values (2); drop function bug11555_1; drop table t1; drop view v1; # BUG#NNNN: New bug synopsis # #--disable_warnings Loading
mysql-test/t/view.test +0 −1 Original line number Diff line number Diff line Loading @@ -1744,7 +1744,6 @@ drop function f1; CHECK TABLE v1, v2, v3, v4, v5, v6; create function f1 () returns int return (select max(col1) from t1); DROP TABLE t1; # following will show underlying table until BUG#11555 fix CHECK TABLE v1, v2, v3, v4, v5, v6; drop function f1; drop function f2; Loading
sql/sp.cc +53 −32 Original line number Diff line number Diff line Loading @@ -1199,6 +1199,12 @@ struct Sroutine_hash_entry for LEX::sroutine/sroutine_list and sp_head::m_sroutines. */ Sroutine_hash_entry *next; /* Uppermost view which directly or indirectly uses this routine. 0 if routine is not used in view. Note that it also can be 0 if statement uses routine both via view and directly. */ TABLE_LIST *belong_to_view; }; Loading Loading @@ -1253,9 +1259,11 @@ void sp_get_prelocking_info(THD *thd, bool *need_prelocking, SYNOPSIS add_used_routine() lex - LEX representing statement arena - arena in which memory for new element will be allocated key - key for the hash representing set lex LEX representing statement arena Arena in which memory for new element will be allocated key Key for the hash representing set belong_to_view Uppermost view which uses this routine (0 if routine is not used by view) NOTES Will also add element to end of 'LEX::sroutines_list' list. Loading @@ -1278,7 +1286,8 @@ void sp_get_prelocking_info(THD *thd, bool *need_prelocking, */ static bool add_used_routine(LEX *lex, Query_arena *arena, const LEX_STRING *key) const LEX_STRING *key, TABLE_LIST *belong_to_view) { if (!hash_search(&lex->sroutines, (byte *)key->str, key->length)) { Loading @@ -1292,6 +1301,7 @@ static bool add_used_routine(LEX *lex, Query_arena *arena, memcpy(rn->key.str, key->str, key->length); my_hash_insert(&lex->sroutines, (byte *)rn); lex->sroutines_list.link_in_list((byte *)rn, (byte **)&rn->next); rn->belong_to_view= belong_to_view; return TRUE; } return FALSE; Loading Loading @@ -1322,7 +1332,7 @@ void sp_add_used_routine(LEX *lex, Query_arena *arena, sp_name *rt, char rt_type) { rt->set_routine_type(rt_type); (void)add_used_routine(lex, arena, &rt->m_sroutines_key); (void)add_used_routine(lex, arena, &rt->m_sroutines_key, 0); lex->sroutines_list_own_last= lex->sroutines_list.next; lex->sroutines_list_own_elements= lex->sroutines_list.elements; } Loading Loading @@ -1392,20 +1402,23 @@ void sp_update_sp_used_routines(HASH *dst, HASH *src) SYNOPSIS sp_update_stmt_used_routines() thd - thread context lex - LEX representing statement src - hash representing set from which routines will be added thd Thread context lex LEX representing statement src Hash representing set from which routines will be added belong_to_view Uppermost view which uses these routines, 0 if none NOTE It will also add elements to end of 'LEX::sroutines_list' list. */ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, HASH *src) static void sp_update_stmt_used_routines(THD *thd, LEX *lex, HASH *src, TABLE_LIST *belong_to_view) { for (uint i=0 ; i < src->records ; i++) { Sroutine_hash_entry *rt= (Sroutine_hash_entry *)hash_element(src, i); (void)add_used_routine(lex, thd->stmt_arena, &rt->key); (void)add_used_routine(lex, thd->stmt_arena, &rt->key, belong_to_view); } } Loading @@ -1419,16 +1432,18 @@ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, HASH *src) thd Thread context lex LEX representing statement src List representing set from which routines will be added belong_to_view Uppermost view which uses these routines, 0 if none NOTE It will also add elements to end of 'LEX::sroutines_list' list. */ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src) static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src, TABLE_LIST *belong_to_view) { for (Sroutine_hash_entry *rt= (Sroutine_hash_entry *)src->first; rt; rt= rt->next) (void)add_used_routine(lex, thd->stmt_arena, &rt->key); (void)add_used_routine(lex, thd->stmt_arena, &rt->key, belong_to_view); } Loading Loading @@ -1533,9 +1548,11 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex, { if (!(first && first_no_prelock)) { sp_update_stmt_used_routines(thd, lex, &sp->m_sroutines); sp_update_stmt_used_routines(thd, lex, &sp->m_sroutines, rt->belong_to_view); tabschnd|= sp->add_used_tables_to_table_list(thd, &lex->query_tables_last); sp->add_used_tables_to_table_list(thd, &lex->query_tables_last, rt->belong_to_view); } } first= FALSE; Loading Loading @@ -1581,9 +1598,9 @@ sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock, SYNOPSIS sp_cache_routines_and_add_tables_for_view() thd - thread context lex - LEX representing statement aux_lex - LEX representing view thd Thread context lex LEX representing statement view Table list element representing view RETURN VALUE 0 - success Loading @@ -1591,11 +1608,12 @@ sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock, */ int sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex) sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, TABLE_LIST *view) { Sroutine_hash_entry **last_cached_routine_ptr= (Sroutine_hash_entry **)lex->sroutines_list.next; sp_update_stmt_used_routines(thd, lex, &aux_lex->sroutines_list); sp_update_stmt_used_routines(thd, lex, &view->view->sroutines_list, view->top_table()); return sp_cache_routines_and_add_tables_aux(thd, lex, *last_cached_routine_ptr, FALSE, NULL); Loading @@ -1609,9 +1627,9 @@ sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex) SYNOPSIS sp_cache_routines_and_add_tables_for_triggers() thd - thread context lex - LEX respresenting statement triggers - triggers of the table thd thread context lex LEX respresenting statement table Table list element for table with trigger RETURN VALUE 0 - success Loading @@ -1620,11 +1638,12 @@ sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex) int sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex, Table_triggers_list *triggers) TABLE_LIST *table) { int ret= 0; if (add_used_routine(lex, thd->stmt_arena, &triggers->sroutines_key)) Table_triggers_list *triggers= table->table->triggers; if (add_used_routine(lex, thd->stmt_arena, &triggers->sroutines_key, table->belong_to_view)) { Sroutine_hash_entry **last_cached_routine_ptr= (Sroutine_hash_entry **)lex->sroutines_list.next; Loading @@ -1634,10 +1653,12 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex, { if (triggers->bodies[i][j]) { (void)triggers->bodies[i][j]->add_used_tables_to_table_list(thd, &lex->query_tables_last); (void)triggers->bodies[i][j]-> add_used_tables_to_table_list(thd, &lex->query_tables_last, table->belong_to_view); sp_update_stmt_used_routines(thd, lex, &triggers->bodies[i][j]->m_sroutines); &triggers->bodies[i][j]->m_sroutines, table->belong_to_view); } } } Loading