Merge mysql.com:/usr/local/bk/mysql-5.0
into mysql.com:/usr/home/pem/bug14233/mysql-5.0
This commit is contained in:
commit
a0ed1d5aba
77
mysql-test/r/sp-destruct.result
Normal file
77
mysql-test/r/sp-destruct.result
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
use test;
|
||||||
|
drop procedure if exists bug14233;
|
||||||
|
drop function if exists bug14233;
|
||||||
|
drop table if exists t1;
|
||||||
|
drop view if exists v1;
|
||||||
|
create procedure bug14233()
|
||||||
|
set @x = 42;
|
||||||
|
create function bug14233_f() returns int
|
||||||
|
return 42;
|
||||||
|
create table t1 (id int);
|
||||||
|
create trigger t1_ai after insert on t1 for each row call bug14233();
|
||||||
|
alter table mysql.proc drop type;
|
||||||
|
call bug14233();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_f. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
|
||||||
|
insert into t1 values (0);
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233. The table mysql.proc is missing, corrupt, or contains bad data (internal code -5)
|
||||||
|
flush table mysql.proc;
|
||||||
|
call bug14233();
|
||||||
|
ERROR HY000: Incorrect information in file: './mysql/proc.frm'
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
ERROR HY000: Incorrect information in file: './mysql/proc.frm'
|
||||||
|
insert into t1 values (0);
|
||||||
|
ERROR HY000: Incorrect information in file: './mysql/proc.frm'
|
||||||
|
flush table mysql.proc;
|
||||||
|
call bug14233();
|
||||||
|
ERROR 42S02: Table 'mysql.proc' doesn't exist
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
ERROR 42S02: Table 'mysql.proc' doesn't exist
|
||||||
|
insert into t1 values (0);
|
||||||
|
ERROR 42S02: Table 'mysql.proc' doesn't exist
|
||||||
|
flush table mysql.proc;
|
||||||
|
flush privileges;
|
||||||
|
delete from mysql.proc where name like 'bug14233%';
|
||||||
|
insert into mysql.proc
|
||||||
|
(
|
||||||
|
db, name, type, specific_name, language, sql_data_access, is_deterministic,
|
||||||
|
security_type, param_list, returns, body, definer, created, modified,
|
||||||
|
sql_mode, comment
|
||||||
|
)
|
||||||
|
values
|
||||||
|
(
|
||||||
|
'test', 'bug14233_1', 'FUNCTION', 'bug14233_1', 'SQL', 'READS_SQL_DATA', 'NO',
|
||||||
|
'DEFINER', '', 'int(10)',
|
||||||
|
'select count(*) from mysql.user',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'test', 'bug14233_2', 'FUNCTION', 'bug14233_2', 'SQL', 'READS_SQL_DATA', 'NO',
|
||||||
|
'DEFINER', '', 'int(10)',
|
||||||
|
'begin declare x int; select count(*) into x from mysql.user; end',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'test', 'bug14233_3', 'PROCEDURE', 'bug14233_3', 'SQL', 'READS_SQL_DATA','NO',
|
||||||
|
'DEFINER', '', '',
|
||||||
|
'alksj wpsj sa ^#!@ ',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
);
|
||||||
|
select bug14233_1();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_1. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
create view v1 as select bug14233_1();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_1. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
select bug14233_2();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
create view v1 as select bug14233_2();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_2. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
call bug14233_3();
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_3. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
drop trigger t1_ai;
|
||||||
|
create trigger t1_ai after insert on t1 for each row call bug14233_3();
|
||||||
|
insert into t1 values (0);
|
||||||
|
ERROR HY000: Failed to load routine test.bug14233_3. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
|
||||||
|
delete from mysql.proc where name like 'bug14233%';
|
||||||
|
drop trigger t1_ai;
|
||||||
|
drop table t1;
|
@ -124,7 +124,7 @@ begin
|
|||||||
declare x int;
|
declare x int;
|
||||||
set x = val+3;
|
set x = val+3;
|
||||||
end|
|
end|
|
||||||
ERROR 42000: No RETURN found in FUNCTION f
|
ERROR 42000: No RETURN found in FUNCTION test.f
|
||||||
create function f(val int) returns int
|
create function f(val int) returns int
|
||||||
begin
|
begin
|
||||||
declare x int;
|
declare x int;
|
||||||
|
124
mysql-test/t/sp-destruct.test
Normal file
124
mysql-test/t/sp-destruct.test
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
#
|
||||||
|
# Destructive stored procedure tests
|
||||||
|
#
|
||||||
|
# We do horrible things to the mysql.proc table here, so any unexpected
|
||||||
|
# failures here might leave it in an undetermined state.
|
||||||
|
#
|
||||||
|
# In the case of trouble you might want to skip this.
|
||||||
|
#
|
||||||
|
|
||||||
|
# We're using --system things that probably doesn't work on Windows.
|
||||||
|
--source include/not_windows.inc
|
||||||
|
|
||||||
|
# Backup proc table
|
||||||
|
--system rm -rf var/master-data/mysql/backup
|
||||||
|
--system mkdir var/master-data/mysql/backup
|
||||||
|
--system cp var/master-data/mysql/proc.* var/master-data/mysql/backup/
|
||||||
|
|
||||||
|
use test;
|
||||||
|
|
||||||
|
--disable_warnings
|
||||||
|
drop procedure if exists bug14233;
|
||||||
|
drop function if exists bug14233;
|
||||||
|
drop table if exists t1;
|
||||||
|
drop view if exists v1;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
create procedure bug14233()
|
||||||
|
set @x = 42;
|
||||||
|
|
||||||
|
create function bug14233_f() returns int
|
||||||
|
return 42;
|
||||||
|
|
||||||
|
create table t1 (id int);
|
||||||
|
create trigger t1_ai after insert on t1 for each row call bug14233();
|
||||||
|
|
||||||
|
# Unsupported tampering with the mysql.proc definition
|
||||||
|
alter table mysql.proc drop type;
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
call bug14233();
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
insert into t1 values (0);
|
||||||
|
|
||||||
|
flush table mysql.proc;
|
||||||
|
|
||||||
|
# Thrashing the .frm file
|
||||||
|
--system echo 'saljdlfa' > var/master-data/mysql/proc.frm
|
||||||
|
--error ER_NOT_FORM_FILE
|
||||||
|
call bug14233();
|
||||||
|
--error ER_NOT_FORM_FILE
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
--error ER_NOT_FORM_FILE
|
||||||
|
insert into t1 values (0);
|
||||||
|
|
||||||
|
|
||||||
|
flush table mysql.proc;
|
||||||
|
|
||||||
|
# Drop the mysql.proc table
|
||||||
|
--system rm var/master-data/mysql/proc.*
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
call bug14233();
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
create view v1 as select bug14233_f();
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
insert into t1 values (0);
|
||||||
|
|
||||||
|
# Restore mysql.proc
|
||||||
|
--system mv var/master-data/mysql/backup/* var/master-data/mysql/
|
||||||
|
--system rmdir var/master-data/mysql/backup
|
||||||
|
|
||||||
|
flush table mysql.proc;
|
||||||
|
flush privileges;
|
||||||
|
|
||||||
|
delete from mysql.proc where name like 'bug14233%';
|
||||||
|
|
||||||
|
# Unsupported editing of mysql.proc, circumventing checks in "create ..."
|
||||||
|
insert into mysql.proc
|
||||||
|
(
|
||||||
|
db, name, type, specific_name, language, sql_data_access, is_deterministic,
|
||||||
|
security_type, param_list, returns, body, definer, created, modified,
|
||||||
|
sql_mode, comment
|
||||||
|
)
|
||||||
|
values
|
||||||
|
(
|
||||||
|
'test', 'bug14233_1', 'FUNCTION', 'bug14233_1', 'SQL', 'READS_SQL_DATA', 'NO',
|
||||||
|
'DEFINER', '', 'int(10)',
|
||||||
|
'select count(*) from mysql.user',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'test', 'bug14233_2', 'FUNCTION', 'bug14233_2', 'SQL', 'READS_SQL_DATA', 'NO',
|
||||||
|
'DEFINER', '', 'int(10)',
|
||||||
|
'begin declare x int; select count(*) into x from mysql.user; end',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'test', 'bug14233_3', 'PROCEDURE', 'bug14233_3', 'SQL', 'READS_SQL_DATA','NO',
|
||||||
|
'DEFINER', '', '',
|
||||||
|
'alksj wpsj sa ^#!@ ',
|
||||||
|
'root@localhost', NOW() , '0000-00-00 00:00:00', '', ''
|
||||||
|
);
|
||||||
|
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
select bug14233_1();
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
create view v1 as select bug14233_1();
|
||||||
|
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
select bug14233_2();
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
create view v1 as select bug14233_2();
|
||||||
|
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
call bug14233_3();
|
||||||
|
drop trigger t1_ai;
|
||||||
|
create trigger t1_ai after insert on t1 for each row call bug14233_3();
|
||||||
|
--error ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
insert into t1 values (0);
|
||||||
|
|
||||||
|
# Clean-up
|
||||||
|
delete from mysql.proc where name like 'bug14233%';
|
||||||
|
drop trigger t1_ai;
|
||||||
|
drop table t1;
|
@ -13,6 +13,8 @@
|
|||||||
# Tests that require multiple connections, except security/privilege tests,
|
# Tests that require multiple connections, except security/privilege tests,
|
||||||
# go to sp-thread.
|
# go to sp-thread.
|
||||||
# Tests that uses 'goto' to into sp-goto.test (currently disabled)
|
# Tests that uses 'goto' to into sp-goto.test (currently disabled)
|
||||||
|
# Tests that destroys system tables (e.g. mysql.proc) for error testing
|
||||||
|
# go to sp-destruct.
|
||||||
|
|
||||||
use test;
|
use test;
|
||||||
|
|
||||||
|
@ -5600,3 +5600,5 @@ ER_OLD_FILE_FORMAT
|
|||||||
eng "'%-.64s' has an old format, you should re-create the '%s' object(s)"
|
eng "'%-.64s' has an old format, you should re-create the '%s' object(s)"
|
||||||
ER_SP_RECURSION_LIMIT
|
ER_SP_RECURSION_LIMIT
|
||||||
eng "Recursive limit %d (as set by the max_sp_recursion_depth variable) was exceeded for routine %.64s"
|
eng "Recursive limit %d (as set by the max_sp_recursion_depth variable) was exceeded for routine %.64s"
|
||||||
|
ER_SP_PROC_TABLE_CORRUPT
|
||||||
|
eng "Failed to load routine %s. The table mysql.proc is missing, corrupt, or contains bad data (internal code %d)"
|
||||||
|
100
sql/sp.cc
100
sql/sp.cc
@ -1446,21 +1446,23 @@ static void sp_update_stmt_used_routines(THD *thd, LEX *lex, SQL_LIST *src)
|
|||||||
first_no_prelock - If true, don't add tables or cache routines used by
|
first_no_prelock - If true, don't add tables or cache routines used by
|
||||||
the body of the first routine (i.e. *start)
|
the body of the first routine (i.e. *start)
|
||||||
will be executed in non-prelocked mode.
|
will be executed in non-prelocked mode.
|
||||||
|
tabs_changed - Set to TRUE some tables were added, FALSE otherwise
|
||||||
NOTE
|
NOTE
|
||||||
If some function is missing this won't be reported here.
|
If some function is missing this won't be reported here.
|
||||||
Instead this fact will be discovered during query execution.
|
Instead this fact will be discovered during query execution.
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
TRUE - some tables were added
|
0 - success
|
||||||
FALSE - no tables were added.
|
non-0 - failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool
|
static int
|
||||||
sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
||||||
Sroutine_hash_entry *start,
|
Sroutine_hash_entry *start,
|
||||||
bool first_no_prelock)
|
bool first_no_prelock, bool *tabs_changed)
|
||||||
{
|
{
|
||||||
bool result= FALSE;
|
int ret= 0;
|
||||||
|
int tabschnd= 0; /* Set if tables changed */
|
||||||
bool first= TRUE;
|
bool first= TRUE;
|
||||||
DBUG_ENTER("sp_cache_routines_and_add_tables_aux");
|
DBUG_ENTER("sp_cache_routines_and_add_tables_aux");
|
||||||
|
|
||||||
@ -1481,12 +1483,45 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
|||||||
name.m_name.str+= 1;
|
name.m_name.str+= 1;
|
||||||
name.m_name.length= name.m_qname.length - name.m_db.length - 1;
|
name.m_name.length= name.m_qname.length - name.m_db.length - 1;
|
||||||
|
|
||||||
if (db_find_routine(thd, type, &name, &sp) == SP_OK)
|
switch ((ret= db_find_routine(thd, type, &name, &sp)))
|
||||||
{
|
{
|
||||||
if (type == TYPE_ENUM_FUNCTION)
|
case SP_OK:
|
||||||
sp_cache_insert(&thd->sp_func_cache, sp);
|
{
|
||||||
else
|
if (type == TYPE_ENUM_FUNCTION)
|
||||||
sp_cache_insert(&thd->sp_proc_cache, sp);
|
sp_cache_insert(&thd->sp_func_cache, sp);
|
||||||
|
else
|
||||||
|
sp_cache_insert(&thd->sp_proc_cache, sp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SP_KEY_NOT_FOUND:
|
||||||
|
ret= SP_OK;
|
||||||
|
break;
|
||||||
|
case SP_OPEN_TABLE_FAILED:
|
||||||
|
/*
|
||||||
|
Force it to attempt opening it again on subsequent calls;
|
||||||
|
otherwise we will get one error message the first time, and
|
||||||
|
then ER_SP_PROC_TABLE_CORRUPT (below) on subsequent tries.
|
||||||
|
*/
|
||||||
|
mysql_proc_table_exists= 1;
|
||||||
|
/* Fall through */
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
Any error when loading an existing routine is either some problem
|
||||||
|
with the mysql.proc table, or a parse error because the contents
|
||||||
|
has been tampered with (in which case we clear that error).
|
||||||
|
*/
|
||||||
|
if (ret == SP_PARSE_ERROR)
|
||||||
|
thd->clear_error();
|
||||||
|
if (!thd->net.report_error)
|
||||||
|
{
|
||||||
|
char n[NAME_LEN*2+2];
|
||||||
|
|
||||||
|
/* m_qname.str is not always \0 terminated */
|
||||||
|
memcpy(n, name.m_qname.str, name.m_qname.length);
|
||||||
|
n[name.m_qname.length]= '\0';
|
||||||
|
my_error(ER_SP_PROC_TABLE_CORRUPT, MYF(0), n, ret);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sp)
|
if (sp)
|
||||||
@ -1494,12 +1529,15 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
|||||||
if (!(first && first_no_prelock))
|
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);
|
||||||
result|= sp->add_used_tables_to_table_list(thd, &lex->query_tables_last);
|
tabschnd|=
|
||||||
|
sp->add_used_tables_to_table_list(thd, &lex->query_tables_last);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
first= FALSE;
|
first= FALSE;
|
||||||
}
|
}
|
||||||
DBUG_RETURN(result);
|
if (tabs_changed) /* it can be NULL */
|
||||||
|
*tabs_changed= tabschnd;
|
||||||
|
DBUG_RETURN(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1514,18 +1552,20 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
|
|||||||
lex - LEX representing statement
|
lex - LEX representing statement
|
||||||
first_no_prelock - If true, don't add tables or cache routines used by
|
first_no_prelock - If true, don't add tables or cache routines used by
|
||||||
the body of the first routine (i.e. *start)
|
the body of the first routine (i.e. *start)
|
||||||
|
tabs_changed - Set to TRUE some tables were added, FALSE otherwise
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
TRUE - some tables were added
|
0 - success
|
||||||
FALSE - no tables were added.
|
non-0 - failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
int
|
||||||
sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock)
|
sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock,
|
||||||
|
bool *tabs_changed)
|
||||||
{
|
{
|
||||||
return sp_cache_routines_and_add_tables_aux(thd, lex,
|
return sp_cache_routines_and_add_tables_aux(thd, lex,
|
||||||
(Sroutine_hash_entry *)lex->sroutines_list.first,
|
(Sroutine_hash_entry *)lex->sroutines_list.first,
|
||||||
first_no_prelock);
|
first_no_prelock, tabs_changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1539,16 +1579,21 @@ sp_cache_routines_and_add_tables(THD *thd, LEX *lex, bool first_no_prelock)
|
|||||||
thd - thread context
|
thd - thread context
|
||||||
lex - LEX representing statement
|
lex - LEX representing statement
|
||||||
aux_lex - LEX representing view
|
aux_lex - LEX representing view
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 - success
|
||||||
|
non-0 - failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
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, LEX *aux_lex)
|
||||||
{
|
{
|
||||||
Sroutine_hash_entry **last_cached_routine_ptr=
|
Sroutine_hash_entry **last_cached_routine_ptr=
|
||||||
(Sroutine_hash_entry **)lex->sroutines_list.next;
|
(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, &aux_lex->sroutines_list);
|
||||||
(void)sp_cache_routines_and_add_tables_aux(thd, lex,
|
return sp_cache_routines_and_add_tables_aux(thd, lex,
|
||||||
*last_cached_routine_ptr, FALSE);
|
*last_cached_routine_ptr, FALSE,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1562,12 +1607,18 @@ sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex, LEX *aux_lex)
|
|||||||
thd - thread context
|
thd - thread context
|
||||||
lex - LEX respresenting statement
|
lex - LEX respresenting statement
|
||||||
triggers - triggers of the table
|
triggers - triggers of the table
|
||||||
|
|
||||||
|
RETURN VALUE
|
||||||
|
0 - success
|
||||||
|
non-0 - failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
int
|
||||||
sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
||||||
Table_triggers_list *triggers)
|
Table_triggers_list *triggers)
|
||||||
{
|
{
|
||||||
|
int ret= 0;
|
||||||
|
|
||||||
if (add_used_routine(lex, thd->stmt_arena, &triggers->sroutines_key))
|
if (add_used_routine(lex, thd->stmt_arena, &triggers->sroutines_key))
|
||||||
{
|
{
|
||||||
Sroutine_hash_entry **last_cached_routine_ptr=
|
Sroutine_hash_entry **last_cached_routine_ptr=
|
||||||
@ -1585,10 +1636,11 @@ sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void)sp_cache_routines_and_add_tables_aux(thd, lex,
|
ret= sp_cache_routines_and_add_tables_aux(thd, lex,
|
||||||
*last_cached_routine_ptr,
|
*last_cached_routine_ptr,
|
||||||
FALSE);
|
FALSE, NULL);
|
||||||
}
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
10
sql/sp.h
10
sql/sp.h
@ -84,11 +84,11 @@ void sp_add_used_routine(LEX *lex, Query_arena *arena,
|
|||||||
sp_name *rt, char rt_type);
|
sp_name *rt, char rt_type);
|
||||||
void sp_remove_not_own_routines(LEX *lex);
|
void sp_remove_not_own_routines(LEX *lex);
|
||||||
void sp_update_sp_used_routines(HASH *dst, HASH *src);
|
void sp_update_sp_used_routines(HASH *dst, HASH *src);
|
||||||
bool sp_cache_routines_and_add_tables(THD *thd, LEX *lex,
|
int sp_cache_routines_and_add_tables(THD *thd, LEX *lex,
|
||||||
bool first_no_prelock);
|
bool first_no_prelock, bool *tabs_changed);
|
||||||
void sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex,
|
int sp_cache_routines_and_add_tables_for_view(THD *thd, LEX *lex,
|
||||||
LEX *aux_lex);
|
LEX *aux_lex);
|
||||||
void sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
int sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
||||||
Table_triggers_list *triggers);
|
Table_triggers_list *triggers);
|
||||||
|
|
||||||
extern "C" byte* sp_sroutine_key(const byte *ptr, uint *plen, my_bool first);
|
extern "C" byte* sp_sroutine_key(const byte *ptr, uint *plen, my_bool first);
|
||||||
|
@ -1984,15 +1984,25 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||||||
if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
|
if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
|
||||||
thd->lex->sroutines_list.elements)
|
thd->lex->sroutines_list.elements)
|
||||||
{
|
{
|
||||||
bool first_no_prelocking, need_prelocking;
|
bool first_no_prelocking, need_prelocking, tabs_changed;
|
||||||
TABLE_LIST **save_query_tables_last= thd->lex->query_tables_last;
|
TABLE_LIST **save_query_tables_last= thd->lex->query_tables_last;
|
||||||
|
|
||||||
DBUG_ASSERT(thd->lex->query_tables == *start);
|
DBUG_ASSERT(thd->lex->query_tables == *start);
|
||||||
sp_get_prelocking_info(thd, &need_prelocking, &first_no_prelocking);
|
sp_get_prelocking_info(thd, &need_prelocking, &first_no_prelocking);
|
||||||
|
|
||||||
if ((sp_cache_routines_and_add_tables(thd, thd->lex,
|
if (sp_cache_routines_and_add_tables(thd, thd->lex,
|
||||||
first_no_prelocking) ||
|
first_no_prelocking,
|
||||||
*start) && need_prelocking)
|
&tabs_changed))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Serious error during reading stored routines from mysql.proc table.
|
||||||
|
Something's wrong with the table or its contents, and an error has
|
||||||
|
been emitted; we must abort.
|
||||||
|
*/
|
||||||
|
result= -1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
else if ((tabs_changed || *start) && need_prelocking)
|
||||||
{
|
{
|
||||||
query_tables_last_own= save_query_tables_last;
|
query_tables_last_own= save_query_tables_last;
|
||||||
*start= thd->lex->query_tables;
|
*start= thd->lex->query_tables;
|
||||||
@ -2116,9 +2126,18 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
|
|||||||
tables->lock_type >= TL_WRITE_ALLOW_WRITE)
|
tables->lock_type >= TL_WRITE_ALLOW_WRITE)
|
||||||
{
|
{
|
||||||
if (!query_tables_last_own)
|
if (!query_tables_last_own)
|
||||||
query_tables_last_own= thd->lex->query_tables_last;
|
query_tables_last_own= thd->lex->query_tables_last;
|
||||||
sp_cache_routines_and_add_tables_for_triggers(thd, thd->lex,
|
if (sp_cache_routines_and_add_tables_for_triggers(thd, thd->lex,
|
||||||
tables->table->triggers);
|
tables->table->triggers))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Serious error during reading stored routines from mysql.proc table.
|
||||||
|
Something's wrong with the table or its contents, and an error has
|
||||||
|
been emitted; we must abort.
|
||||||
|
*/
|
||||||
|
result= -1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC));
|
free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC));
|
||||||
}
|
}
|
||||||
@ -2139,9 +2158,21 @@ process_view_routines:
|
|||||||
/* We have at least one table in TL here. */
|
/* We have at least one table in TL here. */
|
||||||
if (!query_tables_last_own)
|
if (!query_tables_last_own)
|
||||||
query_tables_last_own= thd->lex->query_tables_last;
|
query_tables_last_own= thd->lex->query_tables_last;
|
||||||
sp_cache_routines_and_add_tables_for_view(thd, thd->lex, tables->view);
|
if (sp_cache_routines_and_add_tables_for_view(thd, thd->lex,
|
||||||
|
tables->view))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Serious error during reading stored routines from mysql.proc table.
|
||||||
|
Something's wrong with the table or its contents, and an error has
|
||||||
|
been emitted; we must abort.
|
||||||
|
*/
|
||||||
|
result= -1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err:
|
||||||
thd->proc_info=0;
|
thd->proc_info=0;
|
||||||
free_root(&new_frm_mem, MYF(0)); // Free pre-alloced block
|
free_root(&new_frm_mem, MYF(0)); // Free pre-alloced block
|
||||||
|
|
||||||
|
@ -4133,14 +4133,6 @@ end_with_restore_list:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (lex->sphead->m_type == TYPE_ENUM_FUNCTION &&
|
|
||||||
!(lex->sphead->m_flags & sp_head::HAS_RETURN))
|
|
||||||
{
|
|
||||||
my_error(ER_SP_NORETURN, MYF(0), name);
|
|
||||||
delete lex->sphead;
|
|
||||||
lex->sphead= 0;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We need to copy name and db in order to use them for
|
We need to copy name and db in order to use them for
|
||||||
|
@ -117,7 +117,7 @@ public:
|
|||||||
void set_table(TABLE *new_table);
|
void set_table(TABLE *new_table);
|
||||||
|
|
||||||
friend class Item_trigger_field;
|
friend class Item_trigger_field;
|
||||||
friend void sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
friend int sp_cache_routines_and_add_tables_for_triggers(THD *thd, LEX *lex,
|
||||||
Table_triggers_list *triggers);
|
Table_triggers_list *triggers);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -1407,6 +1407,11 @@ create_function_tail:
|
|||||||
YYABORT;
|
YYABORT;
|
||||||
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
|
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
|
||||||
sp->init_strings(YYTHD, lex, lex->spname);
|
sp->init_strings(YYTHD, lex, lex->spname);
|
||||||
|
if (!(sp->m_flags & sp_head::HAS_RETURN))
|
||||||
|
{
|
||||||
|
my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
|
||||||
|
YYABORT;
|
||||||
|
}
|
||||||
/* Restore flag if it was cleared above */
|
/* Restore flag if it was cleared above */
|
||||||
if (sp->m_old_cmq)
|
if (sp->m_old_cmq)
|
||||||
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
|
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user