List:Commits« Previous MessageNext Message »
From:Davi Arnaut Date:September 28 2007 9:22pm
Subject:bk commit into 5.1 tree (davi:1.2612) BUG#21136
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of davi. When davi does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-09-28 16:22:46-03:00, davi@stripped +3 -0
  Bug#21136 CREATE TABLE SELECT within CREATE TABLE SELECT causes server crash
  
  When CREATE TEMPORARY TABLE .. SELECT is invoked from a stored function
  which in turn is called from CREATE TABLE SELECT causes a memory leak
  because the inner create temporary table overrides the outter extra_lock
  reference when locking the table.
  
  The solution is to simply not overrride the extra_lock by only using the
  extra_lock for a non-temporary table lock.

  mysql-test/r/create.result@stripped, 2007-09-28 16:22:42-03:00, davi@stripped +14 -0
    Add test case result for Bug#21136

  mysql-test/t/create.test@stripped, 2007-09-28 16:22:42-03:00, davi@stripped +25 -0
    Add test case for Bug#21136

  sql/sql_insert.cc@stripped, 2007-09-28 16:22:43-03:00, davi@stripped +18 -7
    For temporary tables, store the lock data within the select_create class
    since tmp tables contents are not replicated. For "real" tables, store
    the lock data in the thread extra_lock pointer.

diff -Nrup a/mysql-test/r/create.result b/mysql-test/r/create.result
--- a/mysql-test/r/create.result	2007-09-10 15:53:15 -03:00
+++ b/mysql-test/r/create.result	2007-09-28 16:22:42 -03:00
@@ -1691,4 +1691,18 @@ ERROR 42000: Identifier name 'очень
 drop view имя_вью_кодировке_утф8_длиной_больше_чем_42;
 drop table
имя_таблицы_в_кодировке_утф8_длиной_больше_чем_48;
 set names default;
+drop table if exists t1,t2,t3;
+drop function if exists f1;
+create function f1() returns int
+begin
+declare res int;
+create temporary table t3 select 1 i;
+set res:= (select count(*) from t1);
+drop temporary table t3;
+return res;
+end|
+create table t1 as select 1;
+create table t2 as select f1() from t1;
+drop table t1,t2;
+drop function f1;
 End of 5.1 tests
diff -Nrup a/mysql-test/t/create.test b/mysql-test/t/create.test
--- a/mysql-test/t/create.test	2007-09-10 15:53:15 -03:00
+++ b/mysql-test/t/create.test	2007-09-28 16:22:42 -03:00
@@ -1303,4 +1303,29 @@ return 0;
 drop view имя_вью_кодировке_утф8_длиной_больше_чем_42;
 drop table
имя_таблицы_в_кодировке_утф8_длиной_больше_чем_48;
 set names default;
+
+#
+# Bug#21136 CREATE TABLE SELECT within CREATE TABLE SELECT causes server crash
+#
+
+--disable_warnings
+drop table if exists t1,t2,t3;
+drop function if exists f1;
+--enable_warnings
+
+--delimiter |
+create function f1() returns int
+begin
+  declare res int;
+  create temporary table t3 select 1 i;
+  set res:= (select count(*) from t1);
+  drop temporary table t3;
+  return res;
+end|
+--delimiter ;
+create table t1 as select 1;
+create table t2 as select f1() from t1;
+drop table t1,t2;
+drop function f1;
+
 --echo End of 5.1 tests
diff -Nrup a/sql/sql_insert.cc b/sql/sql_insert.cc
--- a/sql/sql_insert.cc	2007-09-10 06:42:13 -03:00
+++ b/sql/sql_insert.cc	2007-09-28 16:22:43 -03:00
@@ -3427,6 +3427,7 @@ static TABLE *create_table_from_items(TH
 int
 select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
 {
+  MYSQL_LOCK *extra_lock= NULL;
   DBUG_ENTER("select_create::prepare");
 
   TABLEOP_HOOKS *hook_ptr= NULL;
@@ -3496,9 +3497,19 @@ select_create::prepare(List<Item> &value
 
   if (!(table= create_table_from_items(thd, create_info, create_table,
                                        alter_info, &values,
-                                       &thd->extra_lock, hook_ptr)))
+                                       &extra_lock, hook_ptr)))
     DBUG_RETURN(-1);				// abort() deletes table
 
+  if (extra_lock)
+  {
+    DBUG_ASSERT(m_plock == NULL);
+
+    if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
+      m_plock= &m_lock, m_lock= extra_lock;
+    else
+      m_plock= &thd->extra_lock, thd->extra_lock= extra_lock;
+  }
+
   if (table->s->fields < values.elements)
   {
     my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1);
@@ -3637,10 +3648,10 @@ bool select_create::send_eof()
 
     table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
     table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
-    if (thd->extra_lock)
+    if (m_plock)
     {
-      mysql_unlock_tables(thd, thd->extra_lock);
-      thd->extra_lock=0;
+      mysql_unlock_tables(thd, *m_plock);
+      m_plock= 0;
     }
   }
   return tmp;
@@ -3675,10 +3686,10 @@ void select_create::abort()
   if (thd->current_stmt_binlog_row_based)
     ha_rollback_stmt(thd);
 
-  if (thd->extra_lock)
+  if (m_plock)
   {
-    mysql_unlock_tables(thd, thd->extra_lock);
-    thd->extra_lock=0;
+    mysql_unlock_tables(thd, *m_plock);
+    m_plock= 0;
   }
 
   if (table)
Thread
bk commit into 5.1 tree (davi:1.2612) BUG#21136Davi Arnaut28 Sep
  • Re: bk commit into 5.1 tree (davi:1.2612) BUG#21136Konstantin Osipov28 Sep
    • Re: bk commit into 5.1 tree (davi:1.2612) BUG#21136Davi Arnaut28 Sep