[Commits] Rev 2851: Fix LP BUG#680058 in file:///home/tsk/mprog/src/5.3-mwl89-lpb-680058/

timour at askmonty.org timour at askmonty.org
Wed Nov 24 22:53:49 EET 2010


At file:///home/tsk/mprog/src/5.3-mwl89-lpb-680058/

------------------------------------------------------------
revno: 2851
revision-id: timour at askmonty.org-20101124205340-xdeiqbutf5exwkbp
parent: timour at askmonty.org-20101122220124-8ap7dfnsfz76w1j7
committer: timour at askmonty.org
branch nick: 5.3-mwl89-lpb-680058
timestamp: Wed 2010-11-24 22:53:40 +0200
message:
  Fix LP BUG#680058
  
  Analysis:
  The send_data method of the result sink class used to collect
  data statistics about materialized subqueries incorrectly assumed
  that duplicate rows are removed prior to calling send_data. As
  a result the collected statistics was wrong, which resulted in
  an incorrect maximal number of keys in the Ordered_key buffer.
  
  Solution:
  Try to insert each row into the materialized temp table before
  collecting statistics, and if the insertion results in a duplicate
  row, do not count the current row.
-------------- next part --------------
=== modified file 'mysql-test/r/subselect_partial_match.result'
--- a/mysql-test/r/subselect_partial_match.result	2010-10-27 13:28:19 +0000
+++ b/mysql-test/r/subselect_partial_match.result	2010-11-24 20:53:40 +0000
@@ -48,3 +48,18 @@ select * from t1 where (a1, a2) not in (
 a1      a2
 drop table t1;
 set @@optimizer_switch=@save_optimizer_switch;
+#
+# LP BUG#680058 void Ordered_key::add_key(rownum_t):
+# Assertion `key_buff_elements && cur_key_idx < key_buff_elements' failed
+#
+create table t1 (f1 char(1), f2 char(1));
+insert into t1 values ('t', '0'), ('0', 't');
+create table t2 (f3 char(1), f4 char(1));
+insert into t2 values ('t', NULL), ('t', NULL), ('d', 'y');
+set @save_optimizer_switch=@@optimizer_switch;
+SET @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off,subquery_cache=off,semijoin=off';
+select * from t1 where (f1, f2) not in (select * from t2);
+f1      f2
+0       t
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1, t2;

=== modified file 'mysql-test/t/subselect_partial_match.test'
--- a/mysql-test/t/subselect_partial_match.test	2010-10-27 13:28:19 +0000
+++ b/mysql-test/t/subselect_partial_match.test	2010-11-24 20:53:40 +0000
@@ -54,3 +54,19 @@ explain select * from t1 where (a1, a2) 
 select * from t1 where (a1, a2) not in (select a1, a2 from t1);
 drop table t1;
 set @@optimizer_switch=@save_optimizer_switch;
+
+--echo #
+--echo # LP BUG#680058 void Ordered_key::add_key(rownum_t):
+--echo # Assertion `key_buff_elements && cur_key_idx < key_buff_elements' failed
+--echo #
+
+create table t1 (f1 char(1), f2 char(1));
+insert into t1 values ('t', '0'), ('0', 't');
+create table t2 (f3 char(1), f4 char(1));
+insert into t2 values ('t', NULL), ('t', NULL), ('d', 'y');
+
+set @save_optimizer_switch=@@optimizer_switch;
+SET @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off,subquery_cache=off,semijoin=off';
+select * from t1 where (f1, f2) not in (select * from t2);
+set @@optimizer_switch=@save_optimizer_switch;
+drop table t1, t2;

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2010-11-05 12:42:58 +0000
+++ b/sql/sql_class.cc	2010-11-24 20:53:40 +0000
@@ -3058,6 +3058,13 @@ bool select_materialize_with_stats::send
   Column_statistics *cur_col_stat= col_stat;
   uint nulls_in_row= 0;
 
+  if (select_union::send_data(items))
+    return 1;
+  /* Skip duplicate rows. */
+  if (write_err == HA_ERR_FOUND_DUPP_KEY ||
+      write_err == HA_ERR_FOUND_DUPP_UNIQUE)
+    return 0;
+
   ++count_rows;
 
   while ((cur_item= item_it++))
@@ -3075,7 +3082,7 @@ bool select_materialize_with_stats::send
   if (nulls_in_row > max_nulls_in_row)
     max_nulls_in_row= nulls_in_row;
 
-  return select_union::send_data(items);
+  return 0;
 }
 
 

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2010-11-05 12:42:58 +0000
+++ b/sql/sql_class.h	2010-11-24 20:53:40 +0000
@@ -2973,10 +2973,11 @@ class select_union :public select_result
 {
 protected:
   TMP_TABLE_PARAM tmp_table_param;
+  int write_err; /* Error code from the last send_data->ha_write_row call. */
 public:
   TABLE *table;
 
-  select_union() :table(0) { tmp_table_param.init(); }
+  select_union() :write_err(0),table(0) { tmp_table_param.init(); }
   int prepare(List<Item> &list, SELECT_LEX_UNIT *u);
   bool send_data(List<Item> &items);
   bool send_eof();

=== modified file 'sql/sql_union.cc'
--- a/sql/sql_union.cc	2010-11-05 12:42:58 +0000
+++ b/sql/sql_union.cc	2010-11-24 20:53:40 +0000
@@ -51,7 +51,6 @@ int select_union::prepare(List<Item> &li
 
 bool select_union::send_data(List<Item> &values)
 {
-  int error= 0;
   if (unit->offset_limit_cnt)
   {                                             // using limit offset,count
     unit->offset_limit_cnt--;
@@ -61,14 +60,14 @@ bool select_union::send_data(List<Item> 
   if (thd->is_error())
     return 1;
 
-  if ((error= table->file->ha_write_row(table->record[0])))
+  if ((write_err= table->file->ha_write_row(table->record[0])))
   {
     /* create_internal_tmp_table_from_heap will generate error if needed */
-    if (table->file->is_fatal_error(error, HA_CHECK_DUP) &&
+    if (table->file->is_fatal_error(write_err, HA_CHECK_DUP) &&
         create_internal_tmp_table_from_heap(thd, table,
                                             tmp_table_param.start_recinfo, 
-                                            &tmp_table_param.recinfo, error,
-                                            1))
+                                            &tmp_table_param.recinfo,
+                                            write_err, 1))
       return 1;
   }
   return 0;



More information about the commits mailing list