mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-33218: Assertion `active_arena->is_stmt_prepare_or_first_stmt_execute() || active_arena->state == Query_arena::STMT_SP_QUERY_ARGUMENTS' failed in st_select_lex::fix_prepare_information
In case there is a view that queried from a stored routine or
a prepared statement and this temporary table is dropped between
executions of SP/PS, then it leads to hitting an assertion
at the SELECT_LEX::fix_prepare_information. The fired assertion
was added by the commit 85f2e4f8e8
(MDEV-32466: Potential memory leak on executing of create view statement).
Firing of this assertion means memory leaking on execution of SP/PS.
Moreover, if the added assert be commented out, different result sets
can be produced by the statement SELECT * FROM the hidden table.
Both hitting the assertion and different result sets have the same root
cause. This cause is usage of temporary table's metadata after the table
itself has been dropped. To fix the issue, reload the cache of stored
routines. To do it cache of stored routines is reset at the end of
execution of the function dispatch_command(). Next time any stored routine
be called it will be loaded from the table mysql.proc. This happens inside
the method Sp_handler::sp_cache_routine where loading of a stored routine
is performed in case it missed in cache. Loading is performed unconditionally
while previously it was controlled by the parameter lookup_only. By that
reason the signature of the method Sroutine_hash_entry::sp_cache_routine
was changed by removing unused parameter lookup_only.
Clearing of sp caches affects the test main.lock_sync since it forces
opening and locking the table mysql.proc but the test assumes that each
statement locks its tables once during its execution. To keep this invariant
the debug sync points with names "before_lock_tables_takes_lock" and
"after_lock_tables_takes_lock" are not activated on handling the table
mysql.proc
This commit is contained in:
@ -674,6 +674,60 @@ SHOW TABLES;
|
||||
|
||||
DROP TEMPORARY TABLE t1, t2;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-33218: Assertion `active_arena->is_stmt_prepare_or_first_stmt_execute() || active_arena->state == Query_arena::STMT_SP_QUERY_ARGUMENTS' failed. in st_select_lex::fix_prepare_information
|
||||
--echo #
|
||||
CREATE VIEW v1 AS SELECT 5;
|
||||
CREATE PROCEDURE sp() SELECT * FROM v1;
|
||||
CREATE TEMPORARY TABLE v1 as SELECT 7;
|
||||
--echo # sp() accesses the temporary table v1 that hides the view with the same name
|
||||
--echo # Therefore expected output is the row (7)
|
||||
CALL sp();
|
||||
DROP TEMPORARY TABLE v1;
|
||||
--echo # After the temporary table v1 has been dropped the next invocation of sp()
|
||||
--echo # accesses the view v1. So, expected output is the row (5)
|
||||
CALL sp();
|
||||
|
||||
--echo # Clean up
|
||||
DROP VIEW v1;
|
||||
DROP PROCEDURE sp;
|
||||
|
||||
--echo # Another use case is when a temporary table hides a view is dropped
|
||||
--echo # inside a stored routine being called.
|
||||
|
||||
CREATE VIEW t1 AS SELECT 1;
|
||||
|
||||
--delimiter |
|
||||
CREATE PROCEDURE p1()
|
||||
BEGIN
|
||||
DROP TEMPORARY TABLE t1;
|
||||
END
|
||||
|
|
||||
|
||||
CREATE FUNCTION f1() RETURNS INT
|
||||
BEGIN
|
||||
CALL p1();
|
||||
RETURN 1;
|
||||
END
|
||||
|
|
||||
|
||||
--delimiter ;
|
||||
|
||||
CREATE TEMPORARY TABLE t1 AS SELECT 1 AS a;
|
||||
PREPARE stmt FROM 'SELECT f1()';
|
||||
EXECUTE stmt;
|
||||
--echo # The temporary table t1 has been dropped on first
|
||||
--echo # execution of the prepared statement 'stmt',
|
||||
--echo # next time this statement is run it results in issuing
|
||||
--echo # the error ER_BAD_TABLE_ERROR
|
||||
--error ER_BAD_TABLE_ERROR
|
||||
EXECUTE stmt;
|
||||
|
||||
--echo # Clean up
|
||||
DROP VIEW t1;
|
||||
DROP FUNCTION f1;
|
||||
DROP PROCEDURE p1;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.4 tests
|
||||
--echo #
|
||||
|
Reference in New Issue
Block a user