List:Commits« Previous MessageNext Message »
From:kroki Date:October 25 2006 8:14pm
Subject:bk commit into 5.0 tree (kroki:1.2216) BUG#19182
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of tomash. When tomash 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, 2006-10-25 22:14:40+04:00, kroki@stripped +6 -0
  Bug#19182: CREATE TABLE bar (m INT) SELECT n FROM foo; doesn't work
             from stored procedure.
  
  When CREATE .. SELECT was used from a stored routine or prepared
  statement, on re-execution columns specified in SELECT part could be
  overwritten by columns specified in CREATE part, instead of being added
  to the list of columns.
  
  The cause of a bug was that cached LEX::create_list was modified, and
  then together with LEX::key_list was emtied (instead of being restored to
  original state).
  
  The solution is to restore LEX::create_list to its original state, and to
  not reset LEX::key_list, as it is not modified.

  mysql-test/r/ps_11bugs.result@stripped, 2006-10-25 22:14:37+04:00, kroki@stripped
+19 -0
    Add result for bug#19182: CREATE TABLE bar (m INT) SELECT n FROM foo;
    doesn't work from stored procedure.

  mysql-test/t/ps_11bugs.test@stripped, 2006-10-25 22:14:37+04:00, kroki@stripped +34
-0
    Add test case for bug#19182: CREATE TABLE bar (m INT) SELECT n FROM foo;
    doesn't work from stored procedure.

  sql/sql_insert.cc@stripped, 2006-10-25 22:14:37+04:00, kroki@stripped +12 -0
    Chop off extra fields added to field list, so that original field list
    will stay unmodified after the call.

  sql/sql_list.cc@stripped, 2006-10-25 22:14:37+04:00, kroki@stripped +7 -0
    Add implementation of base_list::remove_after().

  sql/sql_list.h@stripped, 2006-10-25 22:14:37+04:00, kroki@stripped +2 -1
    Add declaration of base_list::remove_after().
    Remove base_list::last_node() method, as it always returns pointer to
    the 'end_of_list' instance.  Add base_list::pnode_last() which returns
    address of the 'next' pointer of the next to last element (or of the
    head of the list, i.e. address of 'first' pointer).

  sql/sql_parse.cc@stripped, 2006-10-25 22:14:37+04:00, kroki@stripped +0 -3
    Remove clearing of LEX::create_list and LEX::key_list.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	kroki
# Host:	moonlight.intranet
# Root:	/home/tomash/src/mysql_ab/mysql-5.0-bug19182

--- 1.194/sql/sql_insert.cc	2006-10-25 22:14:47 +04:00
+++ 1.195/sql/sql_insert.cc	2006-10-25 22:14:47 +04:00
@@ -2471,6 +2471,12 @@ static TABLE *create_table_from_items(TH
   bool not_used;
   DBUG_ENTER("create_table_from_items");
 
+  /*
+    Remember last node so we will be able to chop any elements added
+    later to restore the list to its original state.
+  */
+  list_node **remember_last_node= extra_fields->plast_node();
+
   tmp_table.alias= 0;
   tmp_table.timestamp_field= 0;
   tmp_table.s= &tmp_table.share_not_to_be_used;
@@ -2541,6 +2547,12 @@ static TABLE *create_table_from_items(TH
         quick_rm_table(create_info->db_type, create_table->db,
                        table_case_name(create_info, create_table->table_name));
     }
+
+    /*
+      Chop off extra fields added before the call to mysql_create_table().
+    */
+    extra_fields->remove_after(remember_last_node);
+
     reenable_binlog(thd);
     if (!table)                                   // open failed
       DBUG_RETURN(0);

--- 1.10/sql/sql_list.cc	2006-10-25 22:14:47 +04:00
+++ 1.11/sql/sql_list.cc	2006-10-25 22:14:47 +04:00
@@ -37,3 +37,10 @@ void free_list(I_List <i_string> *list)
   while ((tmp= list->get()))
     delete tmp;
 }
+
+
+void base_list::remove_after(list_node **pnode)
+{
+  while (*pnode != &end_of_list)
+    remove(pnode);
+}

--- 1.39/sql/sql_list.h	2006-10-25 22:14:47 +04:00
+++ 1.40/sql/sql_list.h	2006-10-25 22:14:47 +04:00
@@ -142,6 +142,7 @@ public:
     delete *prev;
     *prev=node;
   }
+  void remove_after(list_node **pnode);
   inline void concat(base_list *list)
   {
     if (!list->is_empty())
@@ -184,7 +185,7 @@ public:
       elements+= list->elements;
     }
   }
-  inline list_node* last_node() { return *last; }
+  inline list_node **plast_node() { return last; }
   inline list_node* first_node() { return first;}
   inline void *head() { return first->info; }
   inline void **head_ref() { return first != &end_of_list ? &first->info : 0;
}

--- 1.561/sql/sql_parse.cc	2006-10-25 22:14:47 +04:00
+++ 1.562/sql/sql_parse.cc	2006-10-25 22:14:47 +04:00
@@ -2947,9 +2947,6 @@ mysql_execute_command(THD *thd)
           res= handle_select(thd, lex, result, 0);
           delete result;
         }
-	/* reset for PS */
-	lex->create_list.empty();
-	lex->key_list.empty();
       }
     }
     else

--- 1.4/mysql-test/r/ps_11bugs.result	2006-10-25 22:14:47 +04:00
+++ 1.5/mysql-test/r/ps_11bugs.result	2006-10-25 22:14:47 +04:00
@@ -130,3 +130,22 @@ prepare st_18492 from 'select * from t1 
 execute st_18492;
 a
 drop table t1;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+CREATE TABLE t1 (i INT);
+PREPARE st_19182 FROM "CREATE TABLE t2 (j INT, KEY (j)) SELECT i FROM t1";
+EXECUTE st_19182;
+DESC t2;
+Field	Type	Null	Key	Default	Extra
+j	int(11)	YES	MUL	NULL	
+i	int(11)	YES		NULL	
+DROP TABLE t2;
+EXECUTE st_19182;
+DESC t2;
+Field	Type	Null	Key	Default	Extra
+j	int(11)	YES	MUL	NULL	
+i	int(11)	YES		NULL	
+DEALLOCATE PREPARE st_19182;
+DROP TABLE t2;
+DROP TABLE t1;
+End of 5.0 tests.

--- 1.6/mysql-test/t/ps_11bugs.test	2006-10-25 22:14:47 +04:00
+++ 1.7/mysql-test/t/ps_11bugs.test	2006-10-25 22:14:47 +04:00
@@ -144,3 +144,37 @@ prepare st_18492 from 'select * from t1 
 execute st_18492;
 
 drop table t1;
+
+
+#
+# Bug#19182: CREATE TABLE bar (m INT) SELECT n FROM foo; doesn't work
+# from stored procedure.
+#
+# The cause of a bug was that cached LEX::create_list was modified,
+# and then together with LEX::key_list was reset.
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+--enable_warnings
+
+CREATE TABLE t1 (i INT);
+
+PREPARE st_19182 FROM "CREATE TABLE t2 (j INT, KEY (j)) SELECT i FROM t1";
+
+EXECUTE st_19182;
+DESC t2;
+
+DROP TABLE t2;
+
+# Check that on second execution we don't loose 'j' column and the key
+# on it.
+EXECUTE st_19182;
+DESC t2;
+
+DEALLOCATE PREPARE st_19182;
+DROP TABLE t2;
+DROP TABLE t1;
+
+
+--echo End of 5.0 tests.
Thread
bk commit into 5.0 tree (kroki:1.2216) BUG#19182kroki25 Oct