mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01: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:
parent
1553a9dd79
commit
b620b3949a
3 changed files with 64 additions and 0 deletions
|
@ -1965,4 +1965,32 @@ b
|
|||
2
|
||||
3
|
||||
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;
|
||||
|
|
|
@ -2760,5 +2760,40 @@ SELECT * FROM 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;
|
||||
--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);
|
||||
cursor_free_list= &cursor_lex->free_list;
|
||||
DBUG_ASSERT(thd->lex == sp_instr_lex);
|
||||
lex_start(thd);
|
||||
}
|
||||
|
||||
thd->lex->sphead= sp;
|
||||
|
|
Loading…
Reference in a new issue