summaryrefslogtreecommitdiff
path: root/storage/innobase/include
diff options
context:
space:
mode:
authorAnnamalai Gurusami <annamalai.gurusami@oracle.com>2014-09-18 15:17:39 +0530
committerAnnamalai Gurusami <annamalai.gurusami@oracle.com>2014-09-18 15:17:39 +0530
commitdb78f29b31566e24f7cdf00f2e93897590149892 (patch)
tree3b016f018676a6b563d0cffe6d8bac7fa43e9487 /storage/innobase/include
parent44fd241a22448f35b00249db567d529a8ae78e7c (diff)
downloadmariadb-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.h8
-rw-r--r--storage/innobase/include/dict0dict.ic12
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));
+}