diff options
author | Annamalai Gurusami <annamalai.gurusami@oracle.com> | 2014-09-18 15:17:39 +0530 |
---|---|---|
committer | Annamalai Gurusami <annamalai.gurusami@oracle.com> | 2014-09-18 15:17:39 +0530 |
commit | db78f29b31566e24f7cdf00f2e93897590149892 (patch) | |
tree | 3b016f018676a6b563d0cffe6d8bac7fa43e9487 /storage/innobase/include | |
parent | 44fd241a22448f35b00249db567d529a8ae78e7c (diff) | |
download | mariadb-git-db78f29b31566e24f7cdf00f2e93897590149892.tar.gz |
Bug #19306524 FAILING ASSERTION WITH TEMP TABLE FOR A PROCEDURE CALLED
FROM A FUNCTION
Scenario:
In a stored procedure, CREATE TABLE statement is not allowed. But an
exception is provided for CREATE TEMPORARY TABLE. We can create a temporary
table in a stored procedure.
Let there be two stored functions f1 and f2 and two stored procedures p1 and
p2. Their properties are as follows:
. stored function f1() calls stored procedure p1().
. stored function f2() calls stored procedure p2().
. stored procedure p1() creates temporary table t1.
. stored procedure p2() does DML on t1.
Consider the following situation:
1. Autocommit mode is on.
2. select f1()
3. select f2()
Step 2: In this step, t1 would be created via p1(). A table level transaction
lock would have been taken. The ::external_lock() would not have been called
on this table. At the end of step 2, because of autocommit mode on, this table
level lock will be released.
Step 3: When we execute DML on table t1 via p2() we have two problems:
Problem 1:
The function ha_innobase::external_lock() would have been called but since
it is a select query no table level locks would have been taken. Hence the
following assert will fail:
ut_ad(lock_table_has(thr_get_trx(thr), index->table, LOCK_IX));
Solution:
The solution would be to identify this situation and take a table level lock
and use the proper lock type prebuilt->select_lock_type = LOCK_X for DML
operations.
Problem 2:
Another problem is that in step 3, ha_innobase::open() is never called on
the table t1.
Solution:
The solution would be to identify this situation and call re-init the handler
of table t1.
rb#6429 approved by Krunal.
Diffstat (limited to 'storage/innobase/include')
-rw-r--r-- | storage/innobase/include/dict0dict.h | 8 | ||||
-rw-r--r-- | storage/innobase/include/dict0dict.ic | 12 |
2 files changed, 20 insertions, 0 deletions
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 254d4e149ca..003639d55b5 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -1367,6 +1367,14 @@ dict_table_init_referenced_rbt( /*===========================*/ dict_table_t* table); /*!< in: the table object whose table->referenced_rbt will be initialized */ +/********************************************************************//** +Check if it is a temporary table. +@return true if temporary table flag is set. */ +UNIV_INLINE +ibool +dict_table_is_temporary( +/*====================*/ + const dict_table_t* table); /*!< in: table to check */ #ifndef UNIV_NONINL #include "dict0dict.ic" diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index a63e1d16427..b65cae2a1d8 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -1004,3 +1004,15 @@ dict_table_init_referenced_rbt( ut_a(table->referenced_rbt != NULL); return(table->referenced_rbt); } + +/********************************************************************//** +Check if it is a temporary table. +@return true if temporary table flag is set. */ +UNIV_INLINE +ibool +dict_table_is_temporary( +/*====================*/ + const dict_table_t* table) /*!< in: table to check */ +{ + return(table->flags & (DICT_TF2_TEMPORARY << DICT_TF2_SHIFT)); +} |