summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorunknown <pem@mysql.telia.com>2003-10-03 12:39:12 +0200
committerunknown <pem@mysql.telia.com>2003-10-03 12:39:12 +0200
commit869b49efe558d6604357c366b2f5594f73e9b7f3 (patch)
tree3f14dd77ac8543b79650a405968fc562326cd0be /sql/sp_head.cc
parent2f468db76ea345783930bacceec45f4d637b3178 (diff)
downloadmariadb-git-869b49efe558d6604357c366b2f5594f73e9b7f3.tar.gz
Fixed BUG#822: Copying and clearing some things in thd/lex when
executing sub-statements (selects) prevents crashes intermittent crashes. Also fixed bug in sql_yacc.yy (generated a hpop instruction when not needed). mysql-test/r/sp.result: Test-case for BUG#822. mysql-test/t/sp.test: Test-case for BUG#822. sql/sp_head.cc: Fixed BUG#822; needed to copy and clear some stuff when calling sub-statements. sql/sql_yacc.yy: Only generate hpop instruction when we actually have handlers.
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc25
1 files changed, 25 insertions, 0 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index f34cb39ab7d..87a4114eba5 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -481,6 +481,13 @@ sp_head::restore_lex(THD *thd)
// Update some state in the old one first
oldlex->ptr= sublex->ptr;
oldlex->next_state= sublex->next_state;
+ // Save WHERE clause pointers to avoid damaging by optimisation
+ for (SELECT_LEX *sl= sublex->all_selects_list ;
+ sl ;
+ sl= sl->next_select_in_list())
+ {
+ sl->prep_where= sl->where;
+ }
// Collect some data from the sub statement lex.
sp_merge_funs(oldlex, sublex);
@@ -578,14 +585,31 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
DBUG_ENTER("sp_instr_stmt::execute");
DBUG_PRINT("info", ("command: %d", m_lex->sql_command));
LEX *olex; // The other lex
+ Item *freelist;
int res;
olex= thd->lex; // Save the other lex
thd->lex= m_lex; // Use my own lex
thd->lex->thd = thd; // QQ Not reentrant!
thd->lex->unit.thd= thd; // QQ Not reentrant
+ freelist= thd->free_list;
+ thd->free_list= NULL;
+ thd->query_id= query_id++;
+
+ // Copy WHERE clause pointers to avoid damaging by optimisation
+ // Also clear ref_pointer_arrays.
+ for (SELECT_LEX *sl= m_lex->all_selects_list ;
+ sl ;
+ sl= sl->next_select_in_list())
+ {
+ sl->ref_pointer_array= 0;
+ if (sl->prep_where)
+ sl->where= sl->prep_where->copy_andor_structure(thd);
+ DBUG_ASSERT(sl->join == 0);
+ }
res= mysql_execute_command(thd);
+
if (thd->lock || thd->open_tables || thd->derived_tables)
{
thd->proc_info="closing tables";
@@ -593,6 +617,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
}
thd->lex= olex; // Restore the other lex
+ thd->free_list= freelist;
*nextp = m_ip+1;
DBUG_RETURN(res);