Commit 87731177 authored by Sergey Glukhov's avatar Sergey Glukhov

Bug#47649 crash during CALL procedure

If first call of the procedure is failed on
the open_table stage stmt_arena->state is set to
EXECUTED state. On second call(if no errors on
open_table stage) it leads to use of worng memory arena
in find_field_in_view() function as
thd->stmt_arena->is_stmt_prepare_or_first_sp_execute()
returns FALSE for EXECUTED state. The item is created 
not in its own arena and it leads to crash on further
calls of the procedure.
The fix: 
change state of arena only if
no errors on open_table stage happens.


mysql-test/r/sp.result:
  test result
mysql-test/t/sp.test:
  test case
sql/sp_head.cc:
  If first call of the procedure is failed on
  the open_table stage stmt_arena->state is set to
  EXECUTED state. On second call(if no errors on
  open_table stage) it leads to use of worng memory arena
  in find_field_in_view() function as
  thd->stmt_arena->is_stmt_prepare_or_first_sp_execute()
  returns FALSE for EXECUTED state. The item is created 
  not in its own arena and it leads to crash on further
  calls of the procedure.
  The fix: 
  change state of arena only if
  no errors on open_table stage happens.
parent 58ccbb7c
...@@ -6963,6 +6963,22 @@ CALL p1(); ...@@ -6963,6 +6963,22 @@ CALL p1();
CALL p1(); CALL p1();
DROP PROCEDURE p1; DROP PROCEDURE p1;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 ( f1 integer, primary key (f1));
CREATE TABLE t2 LIKE t1;
CREATE TEMPORARY TABLE t3 LIKE t1;
CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t3 AS A WHERE A.f1 IN ( SELECT f1 FROM t3 ) ;
END|
CALL p1;
ERROR HY000: Can't reopen table: 'A'
CREATE VIEW t3 AS SELECT f1 FROM t2 A WHERE A.f1 IN ( SELECT f1 FROM t2 );
DROP TABLE t3;
CALL p1;
f1
CALL p1;
f1
DROP PROCEDURE p1;
DROP TABLE t1, t2;
DROP VIEW t3;
# #
# Bug #46629: Item_in_subselect::val_int(): Assertion `0' # Bug #46629: Item_in_subselect::val_int(): Assertion `0'
# on subquery inside a SP # on subquery inside a SP
......
...@@ -8242,6 +8242,25 @@ while ($tab_count) ...@@ -8242,6 +8242,25 @@ while ($tab_count)
DROP PROCEDURE p1; DROP PROCEDURE p1;
DROP TABLE t1; DROP TABLE t1;
#
# Bug#47649 crash during CALL procedure
#
CREATE TABLE t1 ( f1 integer, primary key (f1));
CREATE TABLE t2 LIKE t1;
CREATE TEMPORARY TABLE t3 LIKE t1;
delimiter |;
CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t3 AS A WHERE A.f1 IN ( SELECT f1 FROM t3 ) ;
END|
delimiter ;|
--error ER_CANT_REOPEN_TABLE
CALL p1;
CREATE VIEW t3 AS SELECT f1 FROM t2 A WHERE A.f1 IN ( SELECT f1 FROM t2 );
DROP TABLE t3;
CALL p1;
CALL p1;
DROP PROCEDURE p1;
DROP TABLE t1, t2;
DROP VIEW t3;
--echo # --echo #
--echo # Bug #46629: Item_in_subselect::val_int(): Assertion `0' --echo # Bug #46629: Item_in_subselect::val_int(): Assertion `0'
......
...@@ -2773,8 +2773,15 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, ...@@ -2773,8 +2773,15 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
m_lex->mark_as_requiring_prelocking(NULL); m_lex->mark_as_requiring_prelocking(NULL);
} }
thd->rollback_item_tree_changes(); thd->rollback_item_tree_changes();
/* Update the state of the active arena. */ /*
thd->stmt_arena->state= Query_arena::EXECUTED; Update the state of the active arena if no errors on
open_tables stage.
*/
if (!res || !thd->is_error() ||
(thd->main_da.sql_errno() != ER_CANT_REOPEN_TABLE &&
thd->main_da.sql_errno() != ER_NO_SUCH_TABLE &&
thd->main_da.sql_errno() != ER_UPDATE_TABLE_USED))
thd->stmt_arena->state= Query_arena::EXECUTED;
/* /*
Merge here with the saved parent's values Merge here with the saved parent's values
......
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