1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

MDEV-31661: Assertion `thd->lex == sp_instr_lex' failed in LEX* sp_lex_instr::parse_expr(THD*, sp_head*, LEX*)

This is the follow-up patch for the task MDEV-5816 that fixes assert failure
that happened after recompilation of a stored routine containing a cursor
on its second execution.

The reason of assertion hit is that a state of the SP instruction sp_instr_cpush
wasn't reset after its SQL statement re-compiled.

To fix the issue the virtual method sp_lex_instr::on_after_expr_parsing
is overridden in the derived class sp_instr_cpush. Implementation of this method
does resetting of the data member sp_instr_cpush::m_metadata_changed

Additionally, implementation of the method
 sp_instr_set_trigger_field::on_after_expr_parsing
has been slightly modified to set the data member
 sp_instr_set_trigger_field::value
just before successful return. This data member is used to check whether this
SP instruction is still valid or should be re-compiled.
Resetting this data member before an instance of the class Item_trigger_field
be successfully allocated theoretically could lead to clearing of instruction's
state despite the fact that memory allocation was failed.
This commit is contained in:
Dmitry Shulga
2023-07-19 18:31:01 +07:00
parent 856196ea59
commit 2992d531b0
4 changed files with 63 additions and 3 deletions

View File

@ -2682,4 +2682,35 @@ SET @@debug_dbug=@orig_dbug;
DROP TABLE t1;
DROP TABLE t2;
DROP VIEW v1;
--echo #
--echo # MDEV-31661: Assertion `thd->lex == sp_instr_lex' failed in LEX* sp_lex_instr::parse_expr(THD*, sp_head*, LEX*)
--echo #
--delimiter $
CREATE OR REPLACE PROCEDURE p1()
BEGIN
DECLARE c CURSOR FOR SELECT * FROM t1;
OPEN c;
CLOSE c;
END;
$
--delimiter ;
--error ER_NO_SUCH_TABLE
CALL p1;
CREATE TABLE t1 (id INT);
CALL p1;
--echo # Second execution of the stored procedure p1() after the dependent
--echo # table t1 has been created resulted in assert failure for server built
--echo # with debug
CALL p1;
--echo # Clean up
DROP PROCEDURE p1;
DROP TABLE t1;
SET sql_mode = default;