List:Commits« Previous MessageNext Message »
From:Roy Lyseng Date:June 28 2011 7:24am
Subject:bzr commit into mysql-trunk branch (roy.lyseng:3395)
View as plain text  
#At file:///home/rl136806/mysql/repo/mysql-work0/ based on revid:roy.lyseng@stripped

 3395 Roy Lyseng	2011-06-28
      iBug#12603141: JOIN::flatten_subqueries asrt/simplify_joins sig11/...
      
      When preparing a prepared statement, we need to save a copy of
      WHERE and HAVING condition trees in the prep_where and prep_having
      fields of SELECT_LEX. However, the semantic analysis needs to wrap
      some Item_field objects using Item_ref objects, which are scoped for
      the lifetime of the preparation. This is usually not a problem,
      but when the Item_field is the root object of the condition, the
      Item_ref object is attempted saved in prep_where or prep_having.
      The destructor for the Item_ref is called at the end of the
      preparation, so that when execution of the statement is performed,
      the destroyed Item_ref object will be referenced.
      
      One possible solution to this problem is to detect that the root
      object is an Item_ref object when saving prep_where and prep_having,
      and unwrap this object before saving it. The procedure must be
      applied recursively because sometimes an Item_field is wrapped in
      multiple Item_ref objects.
      
      mysql-test/t/ps.test
        Added test case for bug#12603141.
        
      sql/sql_lex.cc
        In st_select_lex::fix_prepare_information(), unwrap Item_ref
        objects when saving the prep_where and prep_having fields.
      
      sql/sql_select.cc
        In JOIN::optimize(), unwrap Item_ref objects when saving the
        prep_where field.

    modified:
      mysql-test/r/ps.result
      mysql-test/t/ps.test
      sql/sql_lex.cc
      sql/sql_select.cc
=== modified file 'mysql-test/r/ps.result'
--- a/mysql-test/r/ps.result	2011-03-22 12:06:52 +0000
+++ b/mysql-test/r/ps.result	2011-06-28 07:04:32 +0000
@@ -3721,3 +3721,29 @@ FROM (SELECT 1 UNION SELECT 2) t;
 2
 #
 # End of 5.5 tests.
+#
+# Bug#12603141: JOIN::flatten_subqueries asrt/simplify_joins sig11/...
+#
+CREATE TABLE t1(
+a INTEGER PRIMARY KEY
+) engine=Innodb;
+INSERT INTO t1 VALUES (0),(1),(2);
+CREATE TABLE t2(
+a INTEGER PRIMARY KEY
+) engine=Innodb;
+INSERT INTO t2 VALUES (1);
+PREPARE stmt FROM '
+SELECT (SELECT 1 FROM t2 WHERE ot.a) AS d
+FROM t1 AS ot
+GROUP BY d';
+EXECUTE stmt;
+d
+NULL
+1
+EXECUTE stmt;
+d
+NULL
+1
+DROP TABLE t1, t2;
+#
+# End of 5.6 tests.

=== modified file 'mysql-test/t/ps.test'
--- a/mysql-test/t/ps.test	2011-03-22 12:06:52 +0000
+++ b/mysql-test/t/ps.test	2011-06-28 07:04:32 +0000
@@ -3327,4 +3327,28 @@ FROM (SELECT 1 UNION SELECT 2) t;
 --echo #
 --echo # End of 5.5 tests.
 
+--echo #
+--echo # Bug#12603141: JOIN::flatten_subqueries asrt/simplify_joins sig11/...
+--echo #
+
+CREATE TABLE t1(
+  a INTEGER PRIMARY KEY
+) engine=Innodb;
+INSERT INTO t1 VALUES (0),(1),(2);
+CREATE TABLE t2(
+  a INTEGER PRIMARY KEY
+) engine=Innodb;
+INSERT INTO t2 VALUES (1);
+PREPARE stmt FROM '
+SELECT (SELECT 1 FROM t2 WHERE ot.a) AS d
+FROM t1 AS ot
+GROUP BY d';
+EXECUTE stmt;
+EXECUTE stmt;
+DROP TABLE t1, t2;
+
+
+--echo #
+--echo # End of 5.6 tests.
+
 ###########################################################################

=== modified file 'sql/sql_lex.cc'
--- a/sql/sql_lex.cc	2011-04-01 14:04:52 +0000
+++ b/sql/sql_lex.cc	2011-06-28 07:04:32 +0000
@@ -3072,13 +3072,19 @@ void st_select_lex::fix_prepare_informat
     first_execution= 0;
     if (*conds)
     {
-      prep_where= *conds;
-      *conds= where= prep_where->copy_andor_structure(thd);
+      Item *item= *conds;
+      while (item->type() == Item::REF_ITEM)
+        item= *(((Item_ref *)item)->ref);
+      prep_where= item;
+      *conds= where= (*conds)->copy_andor_structure(thd);
     }
     if (*having_conds)
     {
-      prep_having= *having_conds;
-      *having_conds= having= prep_having->copy_andor_structure(thd);
+      Item *item= *having_conds;
+      while (item->type() == Item::REF_ITEM)
+        item= *(((Item_ref *)item)->ref);
+      prep_having= item;
+      *having_conds= having= (*having_conds)->copy_andor_structure(thd);
     }
     fix_prepare_info_in_table_list(thd, table_list.first);
   }

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2011-06-27 07:17:26 +0000
+++ b/sql/sql_select.cc	2011-06-28 07:04:32 +0000
@@ -1904,8 +1904,21 @@ JOIN::optimize()
     conds= simplify_joins(this, join_list, conds, TRUE, FALSE);
     build_bitmap_for_nested_joins(join_list, 0);
 
-    sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0;
-
+    /*
+      This should really have been performed when preparing the select_lex.
+      Doing it now means that we must take care not to include wrapper
+      objects added to the root of the condition tree during
+      execution-time resolving.
+    */
+    if (conds == NULL)
+      sel->prep_where= NULL;
+    else
+    {
+      Item *item= conds;
+      while (item->type() == Item::REF_ITEM)
+        item= *(((Item_ref *)item)->ref);
+      sel->prep_where= item->copy_andor_structure(thd);
+    }
     if (arena)
       thd->restore_active_arena(arena, &backup);
   }


Attachment: [text/bzr-bundle] bzr/roy.lyseng@oracle.com-20110628070432-hbfzhjgsnxnox3h0.bundle
Thread
bzr commit into mysql-trunk branch (roy.lyseng:3395) Roy Lyseng28 Jun