mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-25243 ASAN heap-use-after-free in Item_func_sp::execute_impl upon concurrent view DDL and I_S query with view and function
This commit is contained in:
47
mysql-test/r/information_schema_columns.result
Normal file
47
mysql-test/r/information_schema_columns.result
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#
|
||||||
|
# Start of 10.2 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# MDEV-25243 ASAN heap-use-after-free in Item_func_sp::execute_impl upon concurrent view DDL and I_S query with view and function
|
||||||
|
#
|
||||||
|
CREATE FUNCTION f1() RETURNS INT RETURN 1;
|
||||||
|
CREATE VIEW v01 AS SELECT f1();
|
||||||
|
CREATE VIEW v02 AS SELECT f1();
|
||||||
|
connect con1,localhost,root,,;
|
||||||
|
SELECT GET_LOCK('v01',30);
|
||||||
|
GET_LOCK('v01',30)
|
||||||
|
1
|
||||||
|
SELECT GET_LOCK('v02',30);
|
||||||
|
GET_LOCK('v02',30)
|
||||||
|
1
|
||||||
|
connection default;
|
||||||
|
SELECT * FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA='test'
|
||||||
|
AND TABLE_NAME LIKE 'v0%'
|
||||||
|
AND GET_LOCK(TABLE_NAME,30)
|
||||||
|
AND RELEASE_LOCK(TABLE_NAME)
|
||||||
|
AND f1()=1
|
||||||
|
ORDER BY TABLE_NAME;
|
||||||
|
connection con1;
|
||||||
|
connection con1;
|
||||||
|
SELECT RELEASE_LOCK('v01') /* Let the first row evaluate f1 */;
|
||||||
|
RELEASE_LOCK('v01')
|
||||||
|
1
|
||||||
|
CREATE FUNCTION f2() RETURNS INT RETURN 1 /* Invalidate SP cache*/;
|
||||||
|
SELECT RELEASE_LOCK('v02') /* Let the second row evaluate f1() */;
|
||||||
|
RELEASE_LOCK('v02')
|
||||||
|
1
|
||||||
|
DROP FUNCTION f2;
|
||||||
|
disconnect con1;
|
||||||
|
connection default;
|
||||||
|
SELECT RELEASE_LOCK('v01');
|
||||||
|
RELEASE_LOCK('v01')
|
||||||
|
NULL
|
||||||
|
SELECT RELEASE_LOCK('v02');
|
||||||
|
RELEASE_LOCK('v02')
|
||||||
|
NULL
|
||||||
|
DROP VIEW v01, v02;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
#
|
||||||
|
# End of 10.2 tests
|
||||||
|
#
|
77
mysql-test/r/information_schema_tables.result
Normal file
77
mysql-test/r/information_schema_tables.result
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
#
|
||||||
|
# Start of 10.2 tests
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# MDEV-25243 ASAN heap-use-after-free in Item_func_sp::execute_impl upon concurrent view DDL and I_S query with view and function
|
||||||
|
#
|
||||||
|
# The originally reported non-deterministic test.
|
||||||
|
# It did not fail reliably on every run.
|
||||||
|
CREATE TABLE t (a INT);
|
||||||
|
INSERT INTO t VALUES (1),(2);
|
||||||
|
CREATE FUNCTION f(b INT) RETURNS INT RETURN 1;
|
||||||
|
CREATE VIEW v AS SELECT f(SUM(a)) FROM t;
|
||||||
|
connect con1,localhost,root,,test;
|
||||||
|
LOOP
|
||||||
|
CREATE OR REPLACE VIEW vv AS SELECT 1;
|
||||||
|
END LOOP $
|
||||||
|
connection default;
|
||||||
|
SELECT v.* FROM v JOIN INFORMATION_SCHEMA.TABLES WHERE DATA_LENGTH = -1;
|
||||||
|
f(SUM(a))
|
||||||
|
KILL CONID;
|
||||||
|
disconnect con1;
|
||||||
|
connection default;
|
||||||
|
DROP VIEW IF EXISTS vv;
|
||||||
|
DROP VIEW v;
|
||||||
|
DROP FUNCTION f;
|
||||||
|
DROP TABLE t;
|
||||||
|
# The second test version from the MDEV.
|
||||||
|
# It failed more reliably, but still was not deterministic.
|
||||||
|
CREATE FUNCTION f() RETURNS INT RETURN 1;
|
||||||
|
CREATE VIEW v AS SELECT f() FROM seq_1_to_10;
|
||||||
|
SELECT * FROM INFORMATION_SCHEMA.TABLES, v;;
|
||||||
|
connect con1,localhost,root,,;
|
||||||
|
CREATE VIEW v2 AS SELECT 1;
|
||||||
|
connection default;
|
||||||
|
disconnect con1;
|
||||||
|
DROP VIEW v;
|
||||||
|
DROP VIEW v2;
|
||||||
|
DROP FUNCTION f;
|
||||||
|
# The third test version from the MDEV.
|
||||||
|
# It failed reliably, and should be deterninistic.
|
||||||
|
CREATE FUNCTION f1() RETURNS INT RETURN 1;
|
||||||
|
CREATE VIEW v01 AS SELECT f1();
|
||||||
|
CREATE VIEW v02 AS SELECT f1();
|
||||||
|
connect con1,localhost,root,,;
|
||||||
|
SELECT GET_LOCK('v01',30);
|
||||||
|
GET_LOCK('v01',30)
|
||||||
|
1
|
||||||
|
SELECT GET_LOCK('v02',30);
|
||||||
|
GET_LOCK('v02',30)
|
||||||
|
1
|
||||||
|
connection default;
|
||||||
|
SELECT * FROM INFORMATION_SCHEMA.TABLES
|
||||||
|
WHERE TABLE_SCHEMA='test'
|
||||||
|
AND TABLE_NAME LIKE 'v0%'
|
||||||
|
AND GET_LOCK(TABLE_NAME,30)
|
||||||
|
AND RELEASE_LOCK(TABLE_NAME)
|
||||||
|
AND f1()=1
|
||||||
|
ORDER BY TABLE_NAME;
|
||||||
|
connection con1;
|
||||||
|
SELECT RELEASE_LOCK('v01') /* Let the first row evaluate f1 */;
|
||||||
|
RELEASE_LOCK('v01')
|
||||||
|
1
|
||||||
|
CREATE FUNCTION f2() RETURNS INT RETURN 1 /* Invalidate SP cache*/;
|
||||||
|
SELECT RELEASE_LOCK('v02') /* Let the second row evaluate f1() */;
|
||||||
|
RELEASE_LOCK('v02')
|
||||||
|
1
|
||||||
|
DROP FUNCTION f2;
|
||||||
|
disconnect con1;
|
||||||
|
connection default;
|
||||||
|
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
|
||||||
|
def test v01 VIEW NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL VIEW
|
||||||
|
def test v02 VIEW NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL VIEW
|
||||||
|
DROP VIEW v01, v02;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
#
|
||||||
|
# End of 10.2 tests
|
||||||
|
#
|
48
mysql-test/t/information_schema_columns.test
Normal file
48
mysql-test/t/information_schema_columns.test
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
--echo #
|
||||||
|
--echo # Start of 10.2 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-25243 ASAN heap-use-after-free in Item_func_sp::execute_impl upon concurrent view DDL and I_S query with view and function
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
|
||||||
|
CREATE FUNCTION f1() RETURNS INT RETURN 1;
|
||||||
|
CREATE VIEW v01 AS SELECT f1();
|
||||||
|
CREATE VIEW v02 AS SELECT f1();
|
||||||
|
|
||||||
|
--connect(con1,localhost,root,,)
|
||||||
|
SELECT GET_LOCK('v01',30);
|
||||||
|
SELECT GET_LOCK('v02',30);
|
||||||
|
--connection default
|
||||||
|
|
||||||
|
--send
|
||||||
|
SELECT * FROM INFORMATION_SCHEMA.COLUMNS
|
||||||
|
WHERE TABLE_SCHEMA='test'
|
||||||
|
AND TABLE_NAME LIKE 'v0%'
|
||||||
|
AND GET_LOCK(TABLE_NAME,30)
|
||||||
|
AND RELEASE_LOCK(TABLE_NAME)
|
||||||
|
AND f1()=1
|
||||||
|
ORDER BY TABLE_NAME;
|
||||||
|
|
||||||
|
--connection con1
|
||||||
|
--connection con1
|
||||||
|
SELECT RELEASE_LOCK('v01') /* Let the first row evaluate f1 */;
|
||||||
|
CREATE FUNCTION f2() RETURNS INT RETURN 1 /* Invalidate SP cache*/;
|
||||||
|
SELECT RELEASE_LOCK('v02') /* Let the second row evaluate f1() */;
|
||||||
|
DROP FUNCTION f2;
|
||||||
|
--disconnect con1
|
||||||
|
|
||||||
|
--connection default
|
||||||
|
--disable_result_log
|
||||||
|
--reap
|
||||||
|
--enable_result_log
|
||||||
|
SELECT RELEASE_LOCK('v01');
|
||||||
|
SELECT RELEASE_LOCK('v02');
|
||||||
|
|
||||||
|
DROP VIEW v01, v02;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.2 tests
|
||||||
|
--echo #
|
95
mysql-test/t/information_schema_tables.test
Normal file
95
mysql-test/t/information_schema_tables.test
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
--source include/have_sequence.inc
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Start of 10.2 tests
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-25243 ASAN heap-use-after-free in Item_func_sp::execute_impl upon concurrent view DDL and I_S query with view and function
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo # The originally reported non-deterministic test.
|
||||||
|
--echo # It did not fail reliably on every run.
|
||||||
|
|
||||||
|
CREATE TABLE t (a INT);
|
||||||
|
INSERT INTO t VALUES (1),(2);
|
||||||
|
CREATE FUNCTION f(b INT) RETURNS INT RETURN 1;
|
||||||
|
CREATE VIEW v AS SELECT f(SUM(a)) FROM t;
|
||||||
|
--connect (con1,localhost,root,,test)
|
||||||
|
--let $conid= `SELECT CONNECTION_ID()`
|
||||||
|
--delimiter $
|
||||||
|
--send
|
||||||
|
LOOP
|
||||||
|
CREATE OR REPLACE VIEW vv AS SELECT 1;
|
||||||
|
END LOOP $
|
||||||
|
--delimiter ;
|
||||||
|
--connection default
|
||||||
|
--disable_warnings
|
||||||
|
SELECT v.* FROM v JOIN INFORMATION_SCHEMA.TABLES WHERE DATA_LENGTH = -1;
|
||||||
|
--enable_warnings
|
||||||
|
# Cleanup
|
||||||
|
--replace_result $conid CONID
|
||||||
|
--eval KILL $conid
|
||||||
|
--disconnect con1
|
||||||
|
--connection default
|
||||||
|
DROP VIEW IF EXISTS vv;
|
||||||
|
DROP VIEW v;
|
||||||
|
DROP FUNCTION f;
|
||||||
|
DROP TABLE t;
|
||||||
|
|
||||||
|
|
||||||
|
--echo # The second test version from the MDEV.
|
||||||
|
--echo # It failed more reliably, but still was not deterministic.
|
||||||
|
|
||||||
|
|
||||||
|
CREATE FUNCTION f() RETURNS INT RETURN 1;
|
||||||
|
CREATE VIEW v AS SELECT f() FROM seq_1_to_10;
|
||||||
|
--send SELECT * FROM INFORMATION_SCHEMA.TABLES, v;
|
||||||
|
--connect(con1,localhost,root,,)
|
||||||
|
CREATE VIEW v2 AS SELECT 1;
|
||||||
|
--connection default
|
||||||
|
--disable_result_log
|
||||||
|
--reap
|
||||||
|
--enable_result_log
|
||||||
|
--disconnect con1
|
||||||
|
DROP VIEW v;
|
||||||
|
DROP VIEW v2;
|
||||||
|
DROP FUNCTION f;
|
||||||
|
|
||||||
|
--echo # The third test version from the MDEV.
|
||||||
|
--echo # It failed reliably, and should be deterninistic.
|
||||||
|
|
||||||
|
CREATE FUNCTION f1() RETURNS INT RETURN 1;
|
||||||
|
CREATE VIEW v01 AS SELECT f1();
|
||||||
|
CREATE VIEW v02 AS SELECT f1();
|
||||||
|
|
||||||
|
--connect(con1,localhost,root,,)
|
||||||
|
SELECT GET_LOCK('v01',30);
|
||||||
|
SELECT GET_LOCK('v02',30);
|
||||||
|
--connection default
|
||||||
|
|
||||||
|
--send
|
||||||
|
SELECT * FROM INFORMATION_SCHEMA.TABLES
|
||||||
|
WHERE TABLE_SCHEMA='test'
|
||||||
|
AND TABLE_NAME LIKE 'v0%'
|
||||||
|
AND GET_LOCK(TABLE_NAME,30)
|
||||||
|
AND RELEASE_LOCK(TABLE_NAME)
|
||||||
|
AND f1()=1
|
||||||
|
ORDER BY TABLE_NAME;
|
||||||
|
|
||||||
|
--connection con1
|
||||||
|
SELECT RELEASE_LOCK('v01') /* Let the first row evaluate f1 */;
|
||||||
|
CREATE FUNCTION f2() RETURNS INT RETURN 1 /* Invalidate SP cache*/;
|
||||||
|
SELECT RELEASE_LOCK('v02') /* Let the second row evaluate f1() */;
|
||||||
|
DROP FUNCTION f2;
|
||||||
|
--disconnect con1
|
||||||
|
--connection default
|
||||||
|
--reap
|
||||||
|
|
||||||
|
|
||||||
|
DROP VIEW v01, v02;
|
||||||
|
DROP FUNCTION f1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.2 tests
|
||||||
|
--echo #
|
@@ -313,3 +313,15 @@ sp_cache::cleanup()
|
|||||||
{
|
{
|
||||||
my_hash_free(&m_hashtable);
|
my_hash_free(&m_hashtable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Sp_caches::sp_caches_clear()
|
||||||
|
{
|
||||||
|
sp_cache_clear(&sp_proc_cache);
|
||||||
|
sp_cache_clear(&sp_func_cache);
|
||||||
|
#if MYSQL_VERSION_ID >= 100300
|
||||||
|
#error Remove the preprocessor condition, !!!but keep the code!!!
|
||||||
|
sp_cache_clear(&sp_package_spec_cache);
|
||||||
|
sp_cache_clear(&sp_package_body_cache);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
@@ -806,9 +806,6 @@ THD::THD(my_thread_id id, bool is_wsrep_applier)
|
|||||||
(my_hash_get_key) get_var_key,
|
(my_hash_get_key) get_var_key,
|
||||||
(my_hash_free_key) free_user_var, HASH_THREAD_SPECIFIC);
|
(my_hash_free_key) free_user_var, HASH_THREAD_SPECIFIC);
|
||||||
|
|
||||||
sp_proc_cache= NULL;
|
|
||||||
sp_func_cache= NULL;
|
|
||||||
|
|
||||||
/* For user vars replication*/
|
/* For user vars replication*/
|
||||||
if (opt_bin_log)
|
if (opt_bin_log)
|
||||||
my_init_dynamic_array(&user_var_events,
|
my_init_dynamic_array(&user_var_events,
|
||||||
@@ -1353,8 +1350,7 @@ void THD::change_user(void)
|
|||||||
my_hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
|
my_hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
|
||||||
(my_hash_get_key) get_var_key,
|
(my_hash_get_key) get_var_key,
|
||||||
(my_hash_free_key) free_user_var, 0);
|
(my_hash_free_key) free_user_var, 0);
|
||||||
sp_cache_clear(&sp_proc_cache);
|
sp_caches_clear();
|
||||||
sp_cache_clear(&sp_func_cache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1410,8 +1406,7 @@ void THD::cleanup(void)
|
|||||||
#endif /* defined(ENABLED_DEBUG_SYNC) */
|
#endif /* defined(ENABLED_DEBUG_SYNC) */
|
||||||
|
|
||||||
my_hash_free(&user_vars);
|
my_hash_free(&user_vars);
|
||||||
sp_cache_clear(&sp_proc_cache);
|
sp_caches_clear();
|
||||||
sp_cache_clear(&sp_func_cache);
|
|
||||||
auto_inc_intervals_forced.empty();
|
auto_inc_intervals_forced.empty();
|
||||||
auto_inc_intervals_in_cur_stmt_for_binlog.empty();
|
auto_inc_intervals_in_cur_stmt_for_binlog.empty();
|
||||||
|
|
||||||
|
@@ -2116,6 +2116,51 @@ struct wait_for_commit
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Sp_caches
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
sp_cache *sp_proc_cache;
|
||||||
|
sp_cache *sp_func_cache;
|
||||||
|
#if MYSQL_VERSION_ID >= 100300
|
||||||
|
#error Remove the preprocessor condition, !!!but keep the code!!!
|
||||||
|
sp_cache *sp_package_spec_cache;
|
||||||
|
sp_cache *sp_package_body_cache;
|
||||||
|
#endif
|
||||||
|
Sp_caches()
|
||||||
|
:sp_proc_cache(NULL),
|
||||||
|
sp_func_cache(NULL)
|
||||||
|
#if MYSQL_VERSION_ID >= 100300
|
||||||
|
#error Remove the preprocessor condition, !!!but keep the code!!!
|
||||||
|
,
|
||||||
|
sp_package_spec_cache(NULL),
|
||||||
|
sp_package_body_cache(NULL)
|
||||||
|
#endif
|
||||||
|
{ }
|
||||||
|
~Sp_caches()
|
||||||
|
{
|
||||||
|
// All caches must be freed by the caller explicitly
|
||||||
|
DBUG_ASSERT(sp_proc_cache == NULL);
|
||||||
|
DBUG_ASSERT(sp_func_cache == NULL);
|
||||||
|
#if MYSQL_VERSION_ID >= 100300
|
||||||
|
#error Remove the preprocessor condition, !!!but keep the code!!!
|
||||||
|
DBUG_ASSERT(sp_package_spec_cache == NULL);
|
||||||
|
DBUG_ASSERT(sp_package_body_cache == NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void sp_caches_swap(Sp_caches &rhs)
|
||||||
|
{
|
||||||
|
swap_variables(sp_cache*, sp_proc_cache, rhs.sp_proc_cache);
|
||||||
|
swap_variables(sp_cache*, sp_func_cache, rhs.sp_func_cache);
|
||||||
|
#if MYSQL_VERSION_ID >= 100300
|
||||||
|
#error Remove the preprocessor condition, !!!but keep the code!!!
|
||||||
|
swap_variables(sp_cache*, sp_package_spec_cache, rhs.sp_package_spec_cache);
|
||||||
|
swap_variables(sp_cache*, sp_package_body_cache, rhs.sp_package_body_cache);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
void sp_caches_clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
extern "C" void my_message_sql(uint error, const char *str, myf MyFlags);
|
extern "C" void my_message_sql(uint error, const char *str, myf MyFlags);
|
||||||
|
|
||||||
class THD;
|
class THD;
|
||||||
@@ -2139,7 +2184,8 @@ class THD :public Statement,
|
|||||||
*/
|
*/
|
||||||
public Item_change_list,
|
public Item_change_list,
|
||||||
public MDL_context_owner,
|
public MDL_context_owner,
|
||||||
public Open_tables_state
|
public Open_tables_state,
|
||||||
|
public Sp_caches
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
inline bool is_stmt_prepare() const
|
inline bool is_stmt_prepare() const
|
||||||
@@ -3089,8 +3135,6 @@ public:
|
|||||||
int slave_expected_error;
|
int slave_expected_error;
|
||||||
|
|
||||||
sp_rcontext *spcont; // SP runtime context
|
sp_rcontext *spcont; // SP runtime context
|
||||||
sp_cache *sp_proc_cache;
|
|
||||||
sp_cache *sp_func_cache;
|
|
||||||
|
|
||||||
/** number of name_const() substitutions, see sp_head.cc:subst_spvars() */
|
/** number of name_const() substitutions, see sp_head.cc:subst_spvars() */
|
||||||
uint query_name_consts;
|
uint query_name_consts;
|
||||||
|
@@ -4907,6 +4907,7 @@ public:
|
|||||||
|
|
||||||
int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("get_all_tables");
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
TABLE *table= tables->table;
|
TABLE *table= tables->table;
|
||||||
TABLE_LIST table_acl_check;
|
TABLE_LIST table_acl_check;
|
||||||
@@ -4923,7 +4924,28 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||||||
#endif
|
#endif
|
||||||
uint table_open_method= tables->table_open_method;
|
uint table_open_method= tables->table_open_method;
|
||||||
bool can_deadlock;
|
bool can_deadlock;
|
||||||
DBUG_ENTER("get_all_tables");
|
/*
|
||||||
|
We're going to open FRM files for tables.
|
||||||
|
In case of VIEWs that contain stored function calls,
|
||||||
|
these stored functions will be parsed and put to the SP cache.
|
||||||
|
|
||||||
|
Suppose we have a view containing a stored function call:
|
||||||
|
CREATE VIEW v1 AS SELECT f1() AS c1;
|
||||||
|
and now we're running:
|
||||||
|
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=f1();
|
||||||
|
If a parallel thread invalidates the cache,
|
||||||
|
e.g. by creating or dropping some stored routine,
|
||||||
|
the SELECT query will re-parse f1() when processing "v1"
|
||||||
|
and replace the outdated cached version of f1() to a new one.
|
||||||
|
But the old version of f1() is referenced from the m_sp member
|
||||||
|
of the Item_func_sp instances used in the WHERE condition.
|
||||||
|
We cannot destroy it. To avoid such clashes, let's remember
|
||||||
|
all old routines into a temporary SP cache collection
|
||||||
|
and process tables with a new empty temporary SP cache collection.
|
||||||
|
Then restore to the old SP cache collection at the end.
|
||||||
|
*/
|
||||||
|
Sp_caches old_sp_caches;
|
||||||
|
old_sp_caches.sp_caches_swap(*thd);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
In cases when SELECT from I_S table being filled by this call is
|
In cases when SELECT from I_S table being filled by this call is
|
||||||
@@ -5092,6 +5114,13 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
|
|||||||
err:
|
err:
|
||||||
thd->restore_backup_open_tables_state(&open_tables_state_backup);
|
thd->restore_backup_open_tables_state(&open_tables_state_backup);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Now restore to the saved SP cache collection
|
||||||
|
and clear the temporary SP cache collection.
|
||||||
|
*/
|
||||||
|
old_sp_caches.sp_caches_swap(*thd);
|
||||||
|
old_sp_caches.sp_caches_clear();
|
||||||
|
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user