diff options
author | unknown <pem@mysql.telia.com> | 2003-10-03 12:39:12 +0200 |
---|---|---|
committer | unknown <pem@mysql.telia.com> | 2003-10-03 12:39:12 +0200 |
commit | 869b49efe558d6604357c366b2f5594f73e9b7f3 (patch) | |
tree | 3f14dd77ac8543b79650a405968fc562326cd0be /sql/sp_head.cc | |
parent | 2f468db76ea345783930bacceec45f4d637b3178 (diff) | |
download | mariadb-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.cc | 25 |
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); |