Commit 9c320883 authored by Michael Widenius's avatar Michael Widenius

Fixed that when using a trigger mysql.proc is now accessed

Cleanup:  Changed procedure type from a int/char to an enum for easier to manage and debug code.

mysql-test/r/trigger.result:
  Test that mysql.proc is not used as part of creating or using a trigger.
mysql-test/t/trigger.test:
  Test that mysql.proc is not used as part of creating or using a trigger.
sql/sp.cc:
  The main bug fix is to not look up triggers in mysql.proc; This is done by ignoreing type == TYPE_ENUM_TRIGGER in sp_add_used_routine()
  Cleanup:  Changed procedure type from a int/char to an enum.
sql/sp.h:
  Cleanup:  Changed procedure type from a int/char to an enum.
sql/sp_head.h:
  Cleanup:  Changed procedure type from a int/char to an enum.
sql/sql_db.cc:
  Fix include order
sql/sql_lex.cc:
  Fix include order
sql/sql_parse.cc:
  Cleanup:  Changed procedure type from a int/char to an enum.
sql/sql_show.cc:
  Fix include order
sql/sql_view.cc:
  Fix include order
parent 5f607a2c
...@@ -2117,3 +2117,22 @@ b ...@@ -2117,3 +2117,22 @@ b
DROP DATABASE db1; DROP DATABASE db1;
USE test; USE test;
End of 5.1 tests. End of 5.1 tests.
create table t1 (i int);
create table t2 (i int);
flush tables;
flush status;
CREATE DEFINER=`root`@`localhost` TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW BEGIN DELETE FROM t2 WHERE t2.i = OLD.i; END //
insert into t1 values (1),(2);
insert into t2 values (1),(2);
delete from t1 where i=1;
show status like 'Opened_tables';
Variable_name Value
Opened_tables 3
select * from t1;
i
2
select * from t2;
i
2
drop table t1,t2;
End of 5.2 tests.
...@@ -2409,3 +2409,28 @@ DROP DATABASE db1; ...@@ -2409,3 +2409,28 @@ DROP DATABASE db1;
USE test; USE test;
--echo End of 5.1 tests. --echo End of 5.1 tests.
#
# Test that using a trigger will not open mysql.proc
#
create table t1 (i int);
create table t2 (i int);
flush tables;
flush status;
delimiter //;
CREATE DEFINER=`root`@`localhost` TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW BEGIN DELETE FROM t2 WHERE t2.i = OLD.i; END //
delimiter ;//
insert into t1 values (1),(2);
insert into t2 values (1),(2);
delete from t1 where i=1;
#
# If mysql.proc would be used we would have 4 here. 3 is the correct number.
# (CREATE TRIGGER will open t1 and then flush it)
#
show status like 'Opened_tables';
select * from t1;
select * from t2;
drop table t1,t2;
--echo End of 5.2 tests.
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysql_priv.h" #include "mysql_priv.h"
#include "sp.h"
#include "sp_head.h" #include "sp_head.h"
#include "sp.h"
#include "sp_cache.h" #include "sp_cache.h"
#include "sql_trigger.h" #include "sql_trigger.h"
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
static bool static bool
create_string(THD *thd, String *buf, create_string(THD *thd, String *buf,
int sp_type, stored_procedure_type sp_type,
const char *db, ulong dblen, const char *db, ulong dblen,
const char *name, ulong namelen, const char *name, ulong namelen,
const char *params, ulong paramslen, const char *params, ulong paramslen,
...@@ -33,7 +33,8 @@ create_string(THD *thd, String *buf, ...@@ -33,7 +33,8 @@ create_string(THD *thd, String *buf,
const LEX_STRING *definer_user, const LEX_STRING *definer_user,
const LEX_STRING *definer_host); const LEX_STRING *definer_host);
static int static int
db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, db_load_routine(THD *thd, stored_procedure_type type, sp_name *name,
sp_head **sphp,
ulong sql_mode, const char *params, const char *returns, ulong sql_mode, const char *params, const char *returns,
const char *body, st_sp_chistics &chistics, const char *body, st_sp_chistics &chistics,
const char *definer, longlong created, longlong modified, const char *definer, longlong created, longlong modified,
...@@ -490,7 +491,8 @@ static TABLE *open_proc_table_for_update(THD *thd) ...@@ -490,7 +491,8 @@ static TABLE *open_proc_table_for_update(THD *thd)
*/ */
static int static int
db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table) db_find_routine_aux(THD *thd, stored_procedure_type type, sp_name *name,
TABLE *table)
{ {
uchar key[MAX_KEY_LENGTH]; // db, name, optional key length type uchar key[MAX_KEY_LENGTH]; // db, name, optional key length type
DBUG_ENTER("db_find_routine_aux"); DBUG_ENTER("db_find_routine_aux");
...@@ -543,7 +545,8 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table) ...@@ -543,7 +545,8 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table)
*/ */
static int static int
db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp) db_find_routine(THD *thd, stored_procedure_type type, sp_name *name,
sp_head **sphp)
{ {
TABLE *table; TABLE *table;
const char *params, *returns, *body; const char *params, *returns, *body;
...@@ -711,7 +714,8 @@ Silence_deprecated_warning::handle_error(uint sql_errno, const char *message, ...@@ -711,7 +714,8 @@ Silence_deprecated_warning::handle_error(uint sql_errno, const char *message,
static int static int
db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp, db_load_routine(THD *thd, stored_procedure_type type,
sp_name *name, sp_head **sphp,
ulong sql_mode, const char *params, const char *returns, ulong sql_mode, const char *params, const char *returns,
const char *body, st_sp_chistics &chistics, const char *body, st_sp_chistics &chistics,
const char *definer, longlong created, longlong modified, const char *definer, longlong created, longlong modified,
...@@ -890,7 +894,7 @@ sp_returns_type(THD *thd, String &result, sp_head *sp) ...@@ -890,7 +894,7 @@ sp_returns_type(THD *thd, String &result, sp_head *sp)
*/ */
int int
sp_create_routine(THD *thd, int type, sp_head *sp) sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp)
{ {
int ret; int ret;
TABLE *table; TABLE *table;
...@@ -906,7 +910,8 @@ sp_create_routine(THD *thd, int type, sp_head *sp) ...@@ -906,7 +910,8 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
bool save_binlog_row_based; bool save_binlog_row_based;
DBUG_ENTER("sp_create_routine"); DBUG_ENTER("sp_create_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s",type, (int) sp->m_name.length, DBUG_PRINT("enter", ("type: %d name: %.*s", (int) type,
(int) sp->m_name.length,
sp->m_name.str)); sp->m_name.str));
String retstr(64); String retstr(64);
retstr.set_charset(system_charset_info); retstr.set_charset(system_charset_info);
...@@ -1151,7 +1156,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp) ...@@ -1151,7 +1156,7 @@ sp_create_routine(THD *thd, int type, sp_head *sp)
*/ */
int int
sp_drop_routine(THD *thd, int type, sp_name *name) sp_drop_routine(THD *thd, stored_procedure_type type, sp_name *name)
{ {
TABLE *table; TABLE *table;
int ret; int ret;
...@@ -1211,14 +1216,16 @@ sp_drop_routine(THD *thd, int type, sp_name *name) ...@@ -1211,14 +1216,16 @@ sp_drop_routine(THD *thd, int type, sp_name *name)
*/ */
int int
sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name,
st_sp_chistics *chistics)
{ {
TABLE *table; TABLE *table;
int ret; int ret;
bool save_binlog_row_based; bool save_binlog_row_based;
DBUG_ENTER("sp_update_routine"); DBUG_ENTER("sp_update_routine");
DBUG_PRINT("enter", ("type: %d name: %.*s", DBUG_PRINT("enter", ("type: %d name: %.*s",
type, (int) name->m_name.length, name->m_name.str)); (int) type,
(int) name->m_name.length, name->m_name.str));
DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE || DBUG_ASSERT(type == TYPE_ENUM_PROCEDURE ||
type == TYPE_ENUM_FUNCTION); type == TYPE_ENUM_FUNCTION);
...@@ -1346,7 +1353,7 @@ sp_drop_db_routines(THD *thd, char *db) ...@@ -1346,7 +1353,7 @@ sp_drop_db_routines(THD *thd, char *db)
*/ */
bool bool
sp_show_create_routine(THD *thd, int type, sp_name *name) sp_show_create_routine(THD *thd, stored_procedure_type type, sp_name *name)
{ {
bool err_status= TRUE; bool err_status= TRUE;
sp_head *sp; sp_head *sp;
...@@ -1404,8 +1411,8 @@ sp_show_create_routine(THD *thd, int type, sp_name *name) ...@@ -1404,8 +1411,8 @@ sp_show_create_routine(THD *thd, int type, sp_name *name)
*/ */
sp_head * sp_head *
sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, sp_find_routine(THD *thd, stored_procedure_type type, sp_name *name,
bool cache_only) sp_cache **cp, bool cache_only)
{ {
sp_head *sp; sp_head *sp;
ulong depth= (type == TYPE_ENUM_PROCEDURE ? ulong depth= (type == TYPE_ENUM_PROCEDURE ?
...@@ -1562,7 +1569,7 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any) ...@@ -1562,7 +1569,7 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any)
*/ */
int int
sp_routine_exists_in_table(THD *thd, int type, sp_name *name) sp_routine_exists_in_table(THD *thd, stored_procedure_type type, sp_name *name)
{ {
TABLE *table; TABLE *table;
int ret; int ret;
...@@ -1729,7 +1736,7 @@ static bool add_used_routine(LEX *lex, Query_arena *arena, ...@@ -1729,7 +1736,7 @@ static bool add_used_routine(LEX *lex, Query_arena *arena,
*/ */
void sp_add_used_routine(LEX *lex, Query_arena *arena, void sp_add_used_routine(LEX *lex, Query_arena *arena,
sp_name *rt, char rt_type) sp_name *rt, enum stored_procedure_type rt_type)
{ {
rt->set_routine_type(rt_type); rt->set_routine_type(rt_type);
(void)add_used_routine(lex, arena, &rt->m_sroutines_key, 0); (void)add_used_routine(lex, arena, &rt->m_sroutines_key, 0);
...@@ -1885,9 +1892,11 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex, ...@@ -1885,9 +1892,11 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
for (Sroutine_hash_entry *rt= start; rt; rt= rt->next) for (Sroutine_hash_entry *rt= start; rt; rt= rt->next)
{ {
sp_name name(thd, rt->key.str, rt->key.length); sp_name name(thd, rt->key.str, rt->key.length);
int type= rt->key.str[0]; stored_procedure_type type= (stored_procedure_type) rt->key.str[0];
sp_head *sp; sp_head *sp;
if (type == TYPE_ENUM_TRIGGER)
continue;
if (!(sp= sp_cache_lookup((type == TYPE_ENUM_FUNCTION ? if (!(sp= sp_cache_lookup((type == TYPE_ENUM_FUNCTION ?
&thd->sp_func_cache : &thd->sp_proc_cache), &thd->sp_func_cache : &thd->sp_proc_cache),
&name))) &name)))
...@@ -2076,7 +2085,7 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex, ...@@ -2076,7 +2085,7 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
*/ */
static bool static bool
create_string(THD *thd, String *buf, create_string(THD *thd, String *buf,
int type, stored_procedure_type type,
const char *db, ulong dblen, const char *db, ulong dblen,
const char *name, ulong namelen, const char *name, ulong namelen,
const char *params, ulong paramslen, const char *params, ulong paramslen,
......
...@@ -39,26 +39,28 @@ int ...@@ -39,26 +39,28 @@ int
sp_drop_db_routines(THD *thd, char *db); sp_drop_db_routines(THD *thd, char *db);
sp_head * sp_head *
sp_find_routine(THD *thd, int type, sp_name *name, sp_find_routine(THD *thd, stored_procedure_type type, sp_name *name,
sp_cache **cp, bool cache_only); sp_cache **cp, bool cache_only);
bool bool
sp_exist_routines(THD *thd, TABLE_LIST *procs, bool any); sp_exist_routines(THD *thd, TABLE_LIST *procs, bool any);
int int
sp_routine_exists_in_table(THD *thd, int type, sp_name *name); sp_routine_exists_in_table(THD *thd, stored_procedure_type type,
sp_name *name);
bool bool
sp_show_create_routine(THD *thd, int type, sp_name *name); sp_show_create_routine(THD *thd, stored_procedure_type type, sp_name *name);
int int
sp_create_routine(THD *thd, int type, sp_head *sp); sp_create_routine(THD *thd, stored_procedure_type type, sp_head *sp);
int int
sp_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics); sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name,
st_sp_chistics *chistics);
int int
sp_drop_routine(THD *thd, int type, sp_name *name); sp_drop_routine(THD *thd, stored_procedure_type type, sp_name *name);
/* /*
Procedures for pre-caching of stored routines and building table list Procedures for pre-caching of stored routines and building table list
...@@ -67,7 +69,7 @@ sp_drop_routine(THD *thd, int type, sp_name *name); ...@@ -67,7 +69,7 @@ sp_drop_routine(THD *thd, int type, sp_name *name);
void sp_get_prelocking_info(THD *thd, bool *need_prelocking, void sp_get_prelocking_info(THD *thd, bool *need_prelocking,
bool *first_no_prelocking); bool *first_no_prelocking);
void sp_add_used_routine(LEX *lex, Query_arena *arena, void sp_add_used_routine(LEX *lex, Query_arena *arena,
sp_name *rt, char rt_type); sp_name *rt, stored_procedure_type rt_type);
void sp_remove_not_own_routines(LEX *lex); void sp_remove_not_own_routines(LEX *lex);
bool sp_update_sp_used_routines(HASH *dst, HASH *src); bool sp_update_sp_used_routines(HASH *dst, HASH *src);
int sp_cache_routines_and_add_tables(THD *thd, LEX *lex, int sp_cache_routines_and_add_tables(THD *thd, LEX *lex,
......
...@@ -28,11 +28,16 @@ ...@@ -28,11 +28,16 @@
@ingroup Runtime_Environment @ingroup Runtime_Environment
@{ @{
*/ */
// Values for the type enum. This reflects the order of the enum declaration /*
// in the CREATE TABLE command. Values for the type enum. This reflects the order of the enum declaration
#define TYPE_ENUM_FUNCTION 1 in the CREATE TABLE command.
#define TYPE_ENUM_PROCEDURE 2 */
#define TYPE_ENUM_TRIGGER 3 enum stored_procedure_type
{
TYPE_ENUM_FUNCTION=1,
TYPE_ENUM_PROCEDURE=2,
TYPE_ENUM_TRIGGER=3
};
Item_result Item_result
sp_map_result_type(enum enum_field_types type); sp_map_result_type(enum enum_field_types type);
...@@ -134,9 +139,9 @@ class sp_name : public Sql_alloc ...@@ -134,9 +139,9 @@ class sp_name : public Sql_alloc
// Init. the qualified name from the db and name. // Init. the qualified name from the db and name.
void init_qname(THD *thd); // thd for memroot allocation void init_qname(THD *thd); // thd for memroot allocation
void set_routine_type(char type) void set_routine_type(stored_procedure_type type)
{ {
m_sroutines_key.str[0]= type; m_sroutines_key.str[0]= (char) type;
} }
~sp_name() ~sp_name()
...@@ -170,8 +175,7 @@ class sp_head :private Query_arena ...@@ -170,8 +175,7 @@ class sp_head :private Query_arena
HAS_SQLCOM_FLUSH= 4096 HAS_SQLCOM_FLUSH= 4096
}; };
/** TYPE_ENUM_FUNCTION, TYPE_ENUM_PROCEDURE or TYPE_ENUM_TRIGGER */ stored_procedure_type m_type;
int m_type;
uint m_flags; // Boolean attributes of a stored routine uint m_flags; // Boolean attributes of a stored routine
Create_field m_return_field_def; /**< This is used for FUNCTIONs only. */ Create_field m_return_field_def; /**< This is used for FUNCTIONs only. */
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "mysql_priv.h" #include "mysql_priv.h"
#include <mysys_err.h> #include <mysys_err.h>
#include "sp_head.h"
#include "sp.h" #include "sp.h"
#include "events.h" #include "events.h"
#include <my_dir.h> #include <my_dir.h>
......
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
#include "item_create.h" #include "item_create.h"
#include <m_ctype.h> #include <m_ctype.h>
#include <hash.h> #include <hash.h>
#include "sp.h"
#include "sp_head.h" #include "sp_head.h"
#include "sp.h"
/* /*
We are using pointer to this variable for distinguishing between assignment We are using pointer to this variable for distinguishing between assignment
......
...@@ -4560,9 +4560,10 @@ mysql_execute_command(THD *thd) ...@@ -4560,9 +4560,10 @@ mysql_execute_command(THD *thd)
*/ */
/* Conditionally writes to binlog */ /* Conditionally writes to binlog */
int type= lex->sql_command == SQLCOM_ALTER_PROCEDURE ? stored_procedure_type type;
TYPE_ENUM_PROCEDURE : type= (lex->sql_command == SQLCOM_ALTER_PROCEDURE ?
TYPE_ENUM_FUNCTION; TYPE_ENUM_PROCEDURE :
TYPE_ENUM_FUNCTION);
sp_result= sp_update_routine(thd, sp_result= sp_update_routine(thd,
type, type,
...@@ -4590,8 +4591,8 @@ mysql_execute_command(THD *thd) ...@@ -4590,8 +4591,8 @@ mysql_execute_command(THD *thd)
case SQLCOM_DROP_FUNCTION: case SQLCOM_DROP_FUNCTION:
{ {
int sp_result; int sp_result;
int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ? stored_procedure_type type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION); TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION);
sp_result= sp_routine_exists_in_table(thd, type, lex->spname); sp_result= sp_routine_exists_in_table(thd, type, lex->spname);
mysql_reset_errors(thd, 0); mysql_reset_errors(thd, 0);
...@@ -4618,9 +4619,10 @@ mysql_execute_command(THD *thd) ...@@ -4618,9 +4619,10 @@ mysql_execute_command(THD *thd)
#endif #endif
/* Conditionally writes to binlog */ /* Conditionally writes to binlog */
int type= lex->sql_command == SQLCOM_DROP_PROCEDURE ? stored_procedure_type type;
TYPE_ENUM_PROCEDURE : type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
TYPE_ENUM_FUNCTION; TYPE_ENUM_PROCEDURE :
TYPE_ENUM_FUNCTION);
sp_result= sp_drop_routine(thd, type, lex->spname); sp_result= sp_drop_routine(thd, type, lex->spname);
} }
......
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
#include "create_options.h" #include "create_options.h"
#include "sql_show.h" #include "sql_show.h"
#include "repl_failsafe.h" #include "repl_failsafe.h"
#include "sp.h"
#include "sp_head.h" #include "sp_head.h"
#include "sp.h"
#include "sql_trigger.h" #include "sql_trigger.h"
#include "authors.h" #include "authors.h"
#include "contributors.h" #include "contributors.h"
......
...@@ -18,8 +18,8 @@ ...@@ -18,8 +18,8 @@
#include "mysql_priv.h" #include "mysql_priv.h"
#include "sql_select.h" #include "sql_select.h"
#include "parse_file.h" #include "parse_file.h"
#include "sp.h"
#include "sp_head.h" #include "sp_head.h"
#include "sp.h"
#include "sp_cache.h" #include "sp_cache.h"
#define MD5_BUFF_LENGTH 33 #define MD5_BUFF_LENGTH 33
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment