summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <sergefp@mysql.com>2005-08-10 21:17:02 +0000
committerunknown <sergefp@mysql.com>2005-08-10 21:17:02 +0000
commit6b9ec78be00d37b91d4de8564bc0103d83ddfb26 (patch)
tree5dab1a0ca73f1e4942bf33d79a0b027bc008ab28
parent08cadd816e7fd92f6f56c3ba621aa81d47954fca (diff)
downloadmariadb-git-6b9ec78be00d37b91d4de8564bc0103d83ddfb26.tar.gz
BUG#12228: Post review fixes: Added test case, code cleanup.
mysql-test/r/sp-threads.result: Testcase for BUG#12228 mysql-test/t/sp-threads.test: Testcase for BUG#12228 sql/sp_cache.cc: BUG#12228: Post-review fixes: small code cleanup sql/sp_cache.h: BUG#12228: Post-review fixes: fixed the comment sql/sql_parse.cc: BUG#12228: Post-review fixes: in mysql_parse, flush obsolete SPs from the caches only if the query hasn't been handled by the query cache. sql/sql_prepare.cc: BUG#12228: Post-review fixes: in mysql_stmt_prepare/execute, flush SP caches "closer to the execution"
-rw-r--r--mysql-test/r/sp-threads.result25
-rw-r--r--mysql-test/t/sp-threads.test43
-rw-r--r--sql/sp_cache.cc10
-rw-r--r--sql/sp_cache.h2
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_prepare.cc9
6 files changed, 79 insertions, 14 deletions
diff --git a/mysql-test/r/sp-threads.result b/mysql-test/r/sp-threads.result
index 2f7e8021aa7..c516d7a643f 100644
--- a/mysql-test/r/sp-threads.result
+++ b/mysql-test/r/sp-threads.result
@@ -37,6 +37,7 @@ Id User Host db Command Time State Info
# root localhost test Sleep # NULL
# root localhost test Query # Locked update t1, t2 set val= 1 where id1=id2
# root localhost test Query # NULL show processlist
+# root localhost test Sleep # NULL
unlock tables;
drop procedure bug9486;
drop table t1, t2;
@@ -64,3 +65,27 @@ insert into t1 (select f from v1);
drop function bug11554;
drop table t1;
drop view v1;
+drop procedure if exists p1;
+drop procedure if exists p2;
+create table t1 (s1 int)|
+create procedure p1() select * from t1|
+create procedure p2()
+begin
+insert into t1 values (1);
+call p1();
+select * from t1;
+end|
+use test;
+lock table t1 write;
+ call p2();
+use test;
+drop procedure p1;
+create procedure p1() select * from t1;
+unlock tables;
+s1
+1
+s1
+1
+drop procedure p1;
+drop procedure p2;
+drop table t1;
diff --git a/mysql-test/t/sp-threads.test b/mysql-test/t/sp-threads.test
index 4c192f3e96f..5e51c1034e0 100644
--- a/mysql-test/t/sp-threads.test
+++ b/mysql-test/t/sp-threads.test
@@ -5,6 +5,7 @@
connect (con1root,localhost,root,,);
connect (con2root,localhost,root,,);
+connect (con3root,localhost,root,,);
connection con1root;
use test;
@@ -130,6 +131,48 @@ drop function bug11554;
drop table t1;
drop view v1;
+
+# BUG#12228
+--disable_warnings
+drop procedure if exists p1;
+drop procedure if exists p2;
+--enable_warnings
+
+connection con1root;
+delimiter |;
+create table t1 (s1 int)|
+create procedure p1() select * from t1|
+create procedure p2()
+begin
+ insert into t1 values (1);
+ call p1();
+ select * from t1;
+end|
+delimiter ;|
+
+connection con2root;
+use test;
+lock table t1 write;
+
+connection con1root;
+send call p2();
+
+connection con3root;
+use test;
+drop procedure p1;
+create procedure p1() select * from t1;
+
+connection con2root;
+unlock tables;
+
+connection con1root;
+# Crash will be here if we hit BUG#12228
+reap;
+
+drop procedure p1;
+drop procedure p2;
+drop table t1;
+
#
# BUG#NNNN: New bug synopsis
#
diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc
index 1763432f2bc..68e8dbb3252 100644
--- a/sql/sp_cache.cc
+++ b/sql/sp_cache.cc
@@ -122,19 +122,15 @@ void sp_cache_insert(sp_cache **cp, sp_head *sp)
{
sp_cache *c= *cp;
- if (! c)
+ if (!c && (c= new sp_cache()))
{
- ulong v;
- c= new sp_cache();
pthread_mutex_lock(&Cversion_lock); // LOCK
- v= Cversion;
+ c->version= Cversion;
pthread_mutex_unlock(&Cversion_lock); // UNLOCK
- if (c)
- c->version= v;
}
if (c)
{
- DBUG_PRINT("info",("sp_cache: inserting: %*s", sp->m_qname.length,
+ DBUG_PRINT("info",("sp_cache: inserting: %*s", sp->m_qname.length,
sp->m_qname.str));
c->insert(sp);
if (*cp == NULL)
diff --git a/sql/sp_cache.h b/sql/sp_cache.h
index 402647db9ea..1021d17b9e2 100644
--- a/sql/sp_cache.h
+++ b/sql/sp_cache.h
@@ -46,7 +46,7 @@ class sp_cache;
sp_cache_insert();
sp_cache_invalidate();
- 2.2 When not holding any sp_head* pointers (at query end):
+ 2.2 When not holding any sp_head* pointers:
sp_cache_flush_obsolete();
3. Before thread exit:
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 00463dc0a3b..1a3f6f6f656 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5347,12 +5347,12 @@ void mysql_init_multi_delete(LEX *lex)
void mysql_parse(THD *thd, char *inBuf, uint length)
{
DBUG_ENTER("mysql_parse");
- sp_cache_flush_obsolete(&thd->sp_proc_cache);
- sp_cache_flush_obsolete(&thd->sp_func_cache);
mysql_init_query(thd, (uchar*) inBuf, length);
if (query_cache_send_result_to_client(thd, inBuf, length) <= 0)
{
LEX *lex= thd->lex;
+ sp_cache_flush_obsolete(&thd->sp_proc_cache);
+ sp_cache_flush_obsolete(&thd->sp_func_cache);
if (!yyparse((void *)thd) && ! thd->is_fatal_error)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index f8b19dac3d1..4eb8c00ae16 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1730,8 +1730,6 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
DBUG_ENTER("mysql_stmt_prepare");
DBUG_PRINT("prep_query", ("%s", packet));
- sp_cache_flush_obsolete(&thd->sp_proc_cache);
- sp_cache_flush_obsolete(&thd->sp_func_cache);
/*
If this is an SQLCOM_PREPARE, we also increase Com_prepare_sql.
@@ -1785,6 +1783,9 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
lex= thd->lex;
lex->safe_to_cache_query= 0;
+ sp_cache_flush_obsolete(&thd->sp_proc_cache);
+ sp_cache_flush_obsolete(&thd->sp_func_cache);
+
error= yyparse((void *)thd) || thd->is_fatal_error ||
thd->net.report_error || init_param_array(stmt);
/*
@@ -1981,8 +1982,6 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
Prepared_statement *stmt;
DBUG_ENTER("mysql_stmt_execute");
- sp_cache_flush_obsolete(&thd->sp_proc_cache);
- sp_cache_flush_obsolete(&thd->sp_func_cache);
packet+= 9; /* stmt_id + 5 bytes of flags */
statistic_increment(thd->status_var.com_stmt_execute, &LOCK_status);
@@ -2063,6 +2062,8 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
thd->protocol= &thd->protocol_prep; // Switch to binary protocol
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
+ sp_cache_flush_obsolete(&thd->sp_proc_cache);
+ sp_cache_flush_obsolete(&thd->sp_func_cache);
mysql_execute_command(thd);
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(), WAIT_PRIOR);