[Commits] Rev 2852: Fix LP BUG#680943 in file:///home/tsk/mprog/src/5.3-mwl89-bugfix/

timour at askmonty.org timour at askmonty.org
Tue Nov 30 22:27:45 EET 2010


At file:///home/tsk/mprog/src/5.3-mwl89-bugfix/

------------------------------------------------------------
revno: 2852
revision-id: timour at askmonty.org-20101130202736-h2t6ysuj0r4qws12
parent: timour at askmonty.org-20101126154020-vok9hgwfdch0awut
committer: timour at askmonty.org
branch nick: 5.3-mwl89-bugfix
timestamp: Tue 2010-11-30 22:27:36 +0200
message:
  Fix LP BUG#680943
  
  Analysis:
  The problem lies in filesort.cc:find_all_keys().
  
  When find_all_keys() is called for the outer query, it resets all
  of the tree sets of fields - [read,write,vcol]_set and recomputes
  them with respect to sorting.
  
  However, in the loop for each current record the procedure calls
  select->skip_record(thd), which evaluates the where clause, which
  in turns evaluates the subquery. The JOIN evaluation of the
  subquery eventually calls Field_long::val_int to evaluate the field
  alias1.f1. The assertion condition
    "bitmap_is_set(table->read_set, field_index)"
  fails, because the outer query changed the read_set of table "alias1".
  
  Solution:
  Restore the original read_set of the table before calling
  SQL_SELECT::skip_record, then revert back to the read_set used in
  find_all_keys.
-------------- next part --------------
=== modified file 'mysql-test/r/subselect4.result'
--- a/mysql-test/r/subselect4.result	2010-11-26 15:40:20 +0000
+++ b/mysql-test/r/subselect4.result	2010-11-30 20:27:36 +0000
@@ -527,7 +527,7 @@ id	select_type	table	type	possible_keys	
 DROP TABLE t2;
 DROP TABLE t1;
 #
-# BUG#680846: Crash in clear_tables() with subqueries
+# LP BUG#680846: Crash in clear_tables() with subqueries
 #
 CREATE TABLE t1 (f3 int) ;
 INSERT IGNORE INTO t1 VALUES (0),(0);
@@ -604,3 +604,19 @@ ORDER BY f9;
 COUNT(t2.f3)    f9
 0       NULL
 drop table t1,t2;
+#
+# LP BUG#680943 Assertion `!table || (!table->read_set ||
+# bitmap_is_set(table->read_set, field_index))' failed with subquery
+#
+CREATE TABLE t1 (f1 int,f3 int) ;
+INSERT IGNORE INTO t1 VALUES ('6','0'),('4','0');
+CREATE TABLE t2 (f1 int,f2 int,f3 int) ;
+INSERT IGNORE INTO t2 VALUES ('6','0','0'),('2','0','0');
+SELECT f2
+FROM (SELECT * FROM t2) AS alias1
+WHERE (SELECT SQ2_t2.f1
+FROM t1 JOIN t1 AS SQ2_t2 ON SQ2_t2.f3
+WHERE SQ2_t2.f3 AND alias1.f1)
+ORDER BY f3 ;
+f2
+drop table t1,t2;

=== modified file 'mysql-test/t/subselect4.test'
--- a/mysql-test/t/subselect4.test	2010-11-26 15:40:20 +0000
+++ b/mysql-test/t/subselect4.test	2010-11-30 20:27:36 +0000
@@ -493,7 +493,7 @@ DROP TABLE t2;
 DROP TABLE t1;
 
 --echo #
---echo # BUG#680846: Crash in clear_tables() with subqueries
+--echo # LP BUG#680846: Crash in clear_tables() with subqueries
 --echo #
 
 CREATE TABLE t1 (f3 int) ;
@@ -557,3 +557,23 @@ WHERE ('v') IN (SELECT f4 FROM t2)
 ORDER BY f9;
 
 drop table t1,t2;
+
+--echo #
+--echo # LP BUG#680943 Assertion `!table || (!table->read_set ||
+--echo # bitmap_is_set(table->read_set, field_index))' failed with subquery
+--echo #
+
+CREATE TABLE t1 (f1 int,f3 int) ;
+INSERT IGNORE INTO t1 VALUES ('6','0'),('4','0');
+
+CREATE TABLE t2 (f1 int,f2 int,f3 int) ;
+INSERT IGNORE INTO t2 VALUES ('6','0','0'),('2','0','0');
+
+SELECT f2
+FROM (SELECT * FROM t2) AS alias1
+WHERE (SELECT SQ2_t2.f1
+       FROM t1 JOIN t1 AS SQ2_t2 ON SQ2_t2.f3
+       WHERE SQ2_t2.f3 AND alias1.f1)
+ORDER BY f3 ;
+
+drop table t1,t2;

=== modified file 'sql/filesort.cc'
--- a/sql/filesort.cc	2010-10-10 14:18:11 +0000
+++ b/sql/filesort.cc	2010-11-30 20:27:36 +0000
@@ -613,10 +613,30 @@ static ha_rows find_all_keys(SORTPARAM *
       }
       DBUG_RETURN(HA_POS_ERROR);                /* purecov: inspected */
     }
+
+    bool write_record= false;
     if (error == 0)
+    {
       param->examined_rows++;
-   
-    if (error == 0 && (!select || select->skip_record(thd) > 0))
+      if (select)
+      {
+        /*
+          Restore the original read/write sets of the table 'sort_form' because
+          SQL_SELECT::skip_record evaluates conditions that may include a
+          correlated subquery predicate, such that some field in the subquery
+          refers to 'sort_form'.
+        */
+        sort_form->column_bitmaps_set(save_read_set, save_write_set,
+                                      save_vcol_set);
+        write_record= (select->skip_record(thd) > 0);
+        sort_form->column_bitmaps_set(&sort_form->tmp_set, &sort_form->tmp_set,
+                                      &sort_form->tmp_set);
+      }
+      else
+        write_record= true;
+    }
+
+    if (write_record)
     {
       if (idx == param->keys)
       {
@@ -629,7 +649,7 @@ static ha_rows find_all_keys(SORTPARAM *
     }
     else
       file->unlock_row();
-      
+
     /* It does not make sense to read more keys in case of a fatal error */
     if (thd->is_error())
       break;



More information about the commits mailing list