[Commits] Rev 3488: Fix of LP bug#968720. in file:///home/bell/maria/bzr/work-maria-5.3-lpb968720/

sanja at montyprogram.com sanja at montyprogram.com
Tue Apr 3 13:06:19 EEST 2012


At file:///home/bell/maria/bzr/work-maria-5.3-lpb968720/

------------------------------------------------------------
revno: 3488
revision-id: sanja at montyprogram.com-20120403100617-pax35vl5t8gtmjee
parent: monty at askmonty.org-20120402092715-4cwn2rrcdeafir0x
committer: sanja at montyprogram.com
branch nick: work-maria-5.3-lpb968720
timestamp: Tue 2012-04-03 13:06:17 +0300
message:
  Fix of LP bug#968720.
  
  Problem:
  During converting from merged to materialized all items listed in used_item list changed from real tables to the temporary table of materialized join. The problem was that natural join matching made only once and on second prepare phase (first is prepare opf PREPARE statement, second is prepare phase of executing the statement) the list lack fields of natural join because it is not made second time.
  
  Solution:
  Save the used_items list after natural join matching and restore it during re-initialization.
-------------- next part --------------
=== modified file 'mysql-test/r/derived_view.result'
--- a/mysql-test/r/derived_view.result	2012-03-13 20:34:20 +0000
+++ b/mysql-test/r/derived_view.result	2012-04-03 10:06:17 +0000
@@ -1997,5 +1997,25 @@ a	b	gc
 SET SESSION optimizer_switch= @save_optimizer_switch;
 DROP VIEW v;
 DROP TABLE t1,t2;
+#
+# LP BUG#968720 crash due to converting to materialized and
+# natural join made only once
+#
+set optimizer_switch=@exit_optimizer_switch;
+SET optimizer_switch = 'derived_merge=on';
+CREATE TABLE t1 ( a INT, INDEX(a) ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 ( a INT, INDEX(a) );
+INSERT INTO t2 VALUES (1),(2);
+PREPARE stmt1 FROM "
+INSERT INTO t1
+  SELECT a FROM
+  ( SELECT a FROM test.t1 ) AS alias1
+  NATURAL JOIN t2 AS alias2
+";
+EXECUTE stmt1;
+drop table t1,t2;
+set optimizer_switch=@exit_optimizer_switch;
+end of 5.3 tests
 set optimizer_switch=@exit_optimizer_switch;
 set join_cache_level=@exit_join_cache_level;

=== modified file 'mysql-test/t/derived_view.test'
--- a/mysql-test/t/derived_view.test	2012-03-13 20:34:20 +0000
+++ b/mysql-test/t/derived_view.test	2012-04-03 10:06:17 +0000
@@ -1380,6 +1380,33 @@ SET SESSION optimizer_switch= @save_opti
 DROP VIEW v;
 DROP TABLE t1,t2;
 
+--echo #
+--echo # LP BUG#968720 crash due to converting to materialized and
+--echo # natural join made only once
+--echo #
+
+set optimizer_switch=@exit_optimizer_switch;
+SET optimizer_switch = 'derived_merge=on';
+
+CREATE TABLE t1 ( a INT, INDEX(a) ) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1);
+CREATE TABLE t2 ( a INT, INDEX(a) );
+INSERT INTO t2 VALUES (1),(2);
+
+PREPARE stmt1 FROM "
+INSERT INTO t1
+  SELECT a FROM
+  ( SELECT a FROM test.t1 ) AS alias1
+  NATURAL JOIN t2 AS alias2
+";
+
+EXECUTE stmt1;
+
+drop table t1,t2;
+set optimizer_switch=@exit_optimizer_switch;
+
+--echo end of 5.3 tests
+
 # The following command must be the last one the file 
 set optimizer_switch=@exit_optimizer_switch;
 set join_cache_level=@exit_join_cache_level;

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2012-03-23 16:22:39 +0000
+++ b/sql/sql_base.cc	2012-04-03 10:06:17 +0000
@@ -7276,6 +7276,14 @@ mark_common_columns(THD *thd, TABLE_LIST
   */
   result= FALSE;
 
+  /*
+    Save the lists made during natural join matching (because
+    the matching done only once but we need the list in case
+    of prepared statements).
+  */
+  table_ref_1->save_used_items= table_ref_1->used_items;
+  table_ref_2->save_used_items= table_ref_2->used_items;
+
 err:
   if (arena)
     thd->restore_active_arena(arena, &backup);

=== modified file 'sql/sql_list.h'
--- a/sql/sql_list.h	2012-02-16 14:56:10 +0000
+++ b/sql/sql_list.h	2012-04-03 10:06:17 +0000
@@ -257,6 +257,26 @@ public:
       last= &first;
     return tmp->info;
   }
+
+  /**
+    Cut the list with leaving not more then n elements
+  */
+  inline uint cut(uint n)
+  {
+    list_node *element= first;
+    uint i= 0;
+    for (;
+         i < n && element != &end_of_list;
+         element= element->next);
+    if (element != &end_of_list)
+    {
+      elements= i + 1;
+      last= &element->next;
+      element->next= &end_of_list;
+    }
+    return i + 1;
+  }
+
   /*
     Remove from this list elements that are contained in the passed list. 
     We assume that the passed list is a tail of this list (that is, the whole 

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2012-03-28 10:58:14 +0000
+++ b/sql/table.cc	2012-04-03 10:06:17 +0000
@@ -3540,7 +3540,21 @@ bool TABLE_LIST::create_field_translatio
   Query_arena *arena= thd->stmt_arena, backup;
   bool res= FALSE;
 
-  used_items.empty();
+  if (select->first_natural_join_processing || save_used_items.elements == 0)
+  {
+    /* initialize lists */
+    used_items.empty();
+    save_used_items.empty();
+  }
+  else
+  {
+    /*
+      Copy the list created by natural join procedure because the procedure
+      will not be repeated.
+    */
+    used_items= save_used_items;
+    used_items.cut(save_used_items.elements);
+  }
 
   if (field_translation)
   {

=== modified file 'sql/table.h'
--- a/sql/table.h	2012-03-24 16:08:59 +0000
+++ b/sql/table.h	2012-04-03 10:06:17 +0000
@@ -1601,6 +1601,7 @@ struct TABLE_LIST
   bool          skip_prepare_derived;
 
   List<Item>    used_items;
+  List<Item>    save_used_items;
   Item          **materialized_items;
 
   /* View creation context. */



More information about the commits mailing list