mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-33525: Recreate/reuse temporary table
Calling a stored function that uses a cursor inside its body could produce the error ER_NO_SUCH_TABLE on the second execution in case the cursor uses multi-table query and one of the tables is a temporary table just created before querying the cursor and dropped just after the query has been executed. The reason for issue is that re-parsing of failed a SP instruction caused be create/drop of the temporary table used LEX object left from previous parsing of a SP instruction's query instead re-initialize the lex object before parsing. To fix the issue, add initialization of lex for cursor's statement before re-parsing the query of a failed SP instruction.
This commit is contained in:
@ -1965,4 +1965,32 @@ b
|
|||||||
2
|
2
|
||||||
3
|
3
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
#
|
||||||
|
# MDEV-33525: Recreate/reuse temporary table
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
CREATE FUNCTION f1()
|
||||||
|
RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
DECLARE res INT;
|
||||||
|
DECLARE t1_cur CURSOR FOR SELECT 100 FROM t1, t1_tmp;
|
||||||
|
CREATE TEMPORARY TABLE t1_tmp SELECT 1 a;
|
||||||
|
OPEN t1_cur;
|
||||||
|
CLOSE t1_cur;
|
||||||
|
DROP TEMPORARY TABLE t1_tmp;
|
||||||
|
RETURN 0;
|
||||||
|
END
|
||||||
|
|
|
||||||
|
SELECT f1();
|
||||||
|
f1()
|
||||||
|
0
|
||||||
|
# Without the patch, the second call of f1 would result in error:
|
||||||
|
# ER_NO_SUCH_TABLE (1146): Table 'test.t1' doesn't exist
|
||||||
|
SELECT f1();
|
||||||
|
f1()
|
||||||
|
0
|
||||||
|
# Clean up
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
DROP TABLE t1;
|
||||||
SET sql_mode = default;
|
SET sql_mode = default;
|
||||||
|
@ -2760,5 +2760,40 @@ SELECT * FROM t2;
|
|||||||
|
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-33525: Recreate/reuse temporary table
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
|
||||||
|
--delimiter |
|
||||||
|
CREATE FUNCTION f1()
|
||||||
|
RETURNS INT
|
||||||
|
BEGIN
|
||||||
|
DECLARE res INT;
|
||||||
|
|
||||||
|
DECLARE t1_cur CURSOR FOR SELECT 100 FROM t1, t1_tmp;
|
||||||
|
|
||||||
|
CREATE TEMPORARY TABLE t1_tmp SELECT 1 a;
|
||||||
|
|
||||||
|
OPEN t1_cur;
|
||||||
|
CLOSE t1_cur;
|
||||||
|
|
||||||
|
DROP TEMPORARY TABLE t1_tmp;
|
||||||
|
|
||||||
|
RETURN 0;
|
||||||
|
END
|
||||||
|
|
|
||||||
|
|
||||||
|
--delimiter ;
|
||||||
|
SELECT f1();
|
||||||
|
--echo # Without the patch, the second call of f1 would result in error:
|
||||||
|
--echo # ER_NO_SUCH_TABLE (1146): Table 'test.t1' doesn't exist
|
||||||
|
SELECT f1();
|
||||||
|
|
||||||
|
--echo # Clean up
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
SET sql_mode = default;
|
SET sql_mode = default;
|
||||||
--enable_ps2_protocol
|
--enable_ps2_protocol
|
||||||
|
@ -754,6 +754,7 @@ LEX* sp_lex_instr::parse_expr(THD *thd, sp_head *sp, LEX *sp_instr_lex)
|
|||||||
cleanup_items(cursor_lex->free_list);
|
cleanup_items(cursor_lex->free_list);
|
||||||
cursor_free_list= &cursor_lex->free_list;
|
cursor_free_list= &cursor_lex->free_list;
|
||||||
DBUG_ASSERT(thd->lex == sp_instr_lex);
|
DBUG_ASSERT(thd->lex == sp_instr_lex);
|
||||||
|
lex_start(thd);
|
||||||
}
|
}
|
||||||
|
|
||||||
thd->lex->sphead= sp;
|
thd->lex->sphead= sp;
|
||||||
|
Reference in New Issue
Block a user