← Back to team overview

maria-developers team mailing list archive

Fwd: [Commits] Rev 3092: Fixed bug lp:809245 in file:///home/tsk/mprog/src/5.3-mwl89/

 

Igor,

Could you please review my patch for bug LP:809245.

Ttimour


-------- Original Message --------
Return-Path: <commits-bounces@xxxxxxxxxxx>
X-Original-To: timour@xxxxxxxxxxxx
Delivered-To: timour@xxxxxxxxxxxx
Received: from localhost (localhost.localdomain [127.0.0.1])	by hasky.askmonty.org (Postfix) with ESMTP id 1014BE104C;	Wed, 13 Jul 2011 17:09:26 +0300 (EEST)
X-Virus-Scanned: Debian amavisd-new at mail.askmonty.org
Received: from hasky.askmonty.org ([127.0.0.1])	by localhost (mail.askmonty.org [127.0.0.1]) (amavisd-new, port 10024)	with ESMTP id 2zpPCMRHKtn9; Wed, 13 Jul 2011 17:09:26 +0300 (EEST)
Received: from hasky.askmonty.org (localhost.localdomain [127.0.0.1])	by hasky.askmonty.org (Postfix) with ESMTP id BC862E1049;	Wed, 13 Jul 2011 17:09:26 +0300 (EEST)
Received: by hasky.askmonty.org (Postfix)	id 756A7E1049; Wed, 13 Jul 2011 17:09:25 +0300 (EEST)
Delivered-To: commits@xxxxxxxxxxx
Received: from localhost (localhost.localdomain [127.0.0.1])	by hasky.askmonty.org (Postfix) with ESMTP id 641B3E104A	for <commits@xxxxxxxxxxx>; Wed, 13 Jul 2011 17:09:25 +0300 (EEST)
X-Virus-Scanned: Debian amavisd-new at mail.askmonty.org
Received: from hasky.askmonty.org ([127.0.0.1]) by localhost (mail.askmonty.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id PF4tvWx7nmEU for <commits@xxxxxxxxxxx>; Wed, 13 Jul 2011 17:09:19 +0300 (EEST) Received: from localhost6.localdomain6 (unknown [91.148.138.177]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by hasky.askmonty.org (Postfix) with ESMTPSA id DCEAEE1049 for <commits@xxxxxxxxxxx>; Wed, 13 Jul 2011 17:09:18 +0300 (EEST)
Content-Type: multipart/mixed; boundary="===============3088248604612826632=="
MIME-Version: 1.0
From: <timour@xxxxxxxxxxxx>
User-Agent: bzr/2.3.1
To: <commits@xxxxxxxxxxx>
Message-Id: <20110713140918.DCEAEE1049@xxxxxxxxxxxxxxxxxx>
Date: Wed, 13 Jul 2011 17:09:18 +0300 (EEST)
Subject: [Commits] Rev 3092: Fixed bug lp:809245 in	file:///home/tsk/mprog/src/5.3-mwl89/
X-BeenThere: commits@xxxxxxxxxxx
X-Mailman-Version: 2.1.9
Precedence: list
Reply-To: maria-developers@xxxxxxxxxxxxxxxxxxx
List-Id: MariaDB Commits List <commits.mariadb.org>
List-Unsubscribe: <https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits>, 	<mailto:commits-request@xxxxxxxxxxx?subject=unsubscribe>
List-Archive: <http://lists.askmonty.org/pipermail/commits>
List-Post: <mailto:commits@xxxxxxxxxxx>
List-Help: <mailto:commits-request@xxxxxxxxxxx?subject=help>
List-Subscribe: <https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits>, 	<mailto:commits-request@xxxxxxxxxxx?subject=subscribe>
Sender: commits-bounces@xxxxxxxxxxx
Errors-To: commits-bounces@xxxxxxxxxxx

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

------------------------------------------------------------
revno: 3092
revision-id: timour@xxxxxxxxxxxx-20110713140909-rkka410svyafz4jn
parent: timour@xxxxxxxxxxxx-20110708075646-h4kmmn8mmihfmh1f
fixes bug(s): https://launchpad.net/bugs/809245
committer: timour@xxxxxxxxxxxx
branch nick: 5.3-mwl89
timestamp: Wed 2011-07-13 17:09:09 +0300
message:
  Fixed bug lp:809245

  In addition to the bug fix explained below, the patch performs
  few renames, and adds some comments to avoid similar problems.

  Analysis:
  The failed assert was due to a bug in MWL#68, where it was
  incorrectly assumed that the size of the bitmap
  subselect_rowid_merge_engine::null_only_columns should be
  the same as the size of the array of Ordered_keys.

  The bitmap null_only_columns contains bits to mark columns
  that contain only NULLs. Therefore the indexes of the bits
  to be set in null_only_columns are different from the indexes
  of the Ordered_keys. If there is a NULL-only column that appears
  in a table after the last partial match column with Ordered_key,
  this NULL-only column would require setting a bit with index
  bigger than the size of the bitmap null_only_columns.

  Accessing such a bit caused the failed assert.

  Solution:
  Upon analysis, it turns out that null_only_columns is not needed
  at all, because we are looking for partial matches, and having
  such columns guarantees that there is a partial match for any
  corresponding outer value.

  Therefore the patch removes
    subselect_rowid_merge_engine::null_only_columns.
=== modified file 'mysql-test/r/subselect_partial_match.result'
--- a/mysql-test/r/subselect_partial_match.result	2011-06-05 02:56:06 +0000
+++ b/mysql-test/r/subselect_partial_match.result	2011-07-13 14:09:09 +0000
@@ -1,8 +1,8 @@
+set @save_optimizer_switch=@@optimizer_switch;
 drop table if exists t1, t2;
 #
 # LP BUG#608744
 #
-set @save_optimizer_switch=@@optimizer_switch;
 set @@optimizer_switch="materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=off";
 create table t1 (a1 char(1), a2 char(1));
 insert into t1 values (NULL, 'b');
@@ -11,7 +11,6 @@ insert into t2 values ('a','b'), ('c', '
 select * from t1 where (a1, a2) NOT IN (select b1, b2 from t2);
 a1      a2
 drop table t1,t2;
-set @@optimizer_switch=@save_optimizer_switch;
 #
 # LP BUG#601156
 #
@@ -21,7 +20,6 @@ INSERT INTO t1 VALUES (4,NULL);
 CREATE TABLE t2 (b1 int DEFAULT NULL, b2 int DEFAULT NULL);
 INSERT INTO t2 VALUES (6,NULL);
 INSERT INTO t2 VALUES (NULL,0);
-set @save_optimizer_switch=@@optimizer_switch;
 set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on';
 EXPLAIN EXTENDED
 SELECT * FROM (SELECT * FROM t1 WHERE a1 NOT IN (SELECT b2 FROM t2)) table1;
@@ -31,11 +29,9 @@ id	select_type	table	type	possible_keys
 Warnings:
 Note    1003    select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where (not(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b2` from `test`.`t2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery3>`.`b2`)))))))
 DROP TABLE t1, t2;
-set @@optimizer_switch=@save_optimizer_switch;
 #
 # LP BUG#613009 Crash in Ordered_key::get_field_idx
 #
-set @save_optimizer_switch=@@optimizer_switch;
 set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=off';
 create table t1 (a1 char(3) DEFAULT NULL, a2 char(3) DEFAULT NULL);
 insert into t1 values (NULL, 'a21'), (NULL, 'a22');
@@ -46,7 +42,6 @@ id	select_type	table	type	possible_keys
 select * from t1 where (a1, a2) not in (select a1, a2 from t1);
 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
@@ -55,10 +50,53 @@ 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,semijoin=off';
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=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;
+#
+# LP BUG#809245 Second assertion `bit < (map)->n_bits' with partial_match_merge
+#
+CREATE TABLE t1 (d varchar(32)) ;
+INSERT INTO t1 VALUES ('r');
+CREATE TABLE t2 ( a int, c varchar(32)) ;
+INSERT INTO t2 VALUES (5,'r');
+CREATE TABLE t3 ( a int NOT NULL , d varchar(32)) ;
+INSERT INTO t3 VALUES (10,'g');
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off';
+EXPLAIN SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+SELECT t3.d , t2.c
+FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+id      select_type     table   type    possible_keys   key     key_len ref     rows    Extra
+1       PRIMARY t1      system  NULL    NULL    NULL    NULL    1       
+2       SUBQUERY        t3      system  NULL    NULL    NULL    NULL    1       
+2       SUBQUERY        t2      system  NULL    NULL    NULL    NULL    1       
+SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+SELECT t3.d , t2.c
+FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+d
+r
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+EXPLAIN SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+SELECT t3.d , t2.c
+FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+id      select_type     table   type    possible_keys   key     key_len ref     rows    Extra
+1       PRIMARY t1      system  NULL    NULL    NULL    NULL    1       
+2       DEPENDENT SUBQUERY      t3      system  NULL    NULL    NULL    NULL    1       
+2       DEPENDENT SUBQUERY      t2      system  NULL    NULL    NULL    NULL    1       
+SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+SELECT t3.d , t2.c
+FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+d
+r
+drop table t1, t2, t3;
+set @@optimizer_switch=@save_optimizer_switch;

=== modified file 'mysql-test/t/subselect_partial_match.test'
--- a/mysql-test/t/subselect_partial_match.test	2010-11-24 22:34:50 +0000
+++ b/mysql-test/t/subselect_partial_match.test	2011-07-13 14:09:09 +0000
@@ -3,6 +3,8 @@
 # MWL#68: Subquery optimization: Efficient NOT IN execution with NULLs
 #
 
+set @save_optimizer_switch=@@optimizer_switch;
+
 --disable_warnings
 drop table if exists t1, t2;
 --enable_warnings
@@ -10,7 +12,6 @@ drop table if exists t1, t2;
 --echo #
 --echo # LP BUG#608744
 --echo #
-set @save_optimizer_switch=@@optimizer_switch;
 set @@optimizer_switch="materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=off";
 create table t1 (a1 char(1), a2 char(1));
 insert into t1 values (NULL, 'b');
@@ -18,7 +19,6 @@ create table t2 (b1 char(1), b2 char(2))
 insert into t2 values ('a','b'), ('c', 'd');
 select * from t1 where (a1, a2) NOT IN (select b1, b2 from t2);
 drop table t1,t2;
-set @@optimizer_switch=@save_optimizer_switch;
 
 
 --echo #
@@ -32,20 +32,17 @@ CREATE TABLE t2 (b1 int DEFAULT NULL, b2
 INSERT INTO t2 VALUES (6,NULL);
 INSERT INTO t2 VALUES (NULL,0);
 
-set @save_optimizer_switch=@@optimizer_switch;
 set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=on';
 
 EXPLAIN EXTENDED
 SELECT * FROM (SELECT * FROM t1 WHERE a1 NOT IN (SELECT b2 FROM t2)) table1;
 
 DROP TABLE t1, t2;
-set @@optimizer_switch=@save_optimizer_switch;
 
 --echo #
 --echo # LP BUG#613009 Crash in Ordered_key::get_field_idx
 --echo #
 
-set @save_optimizer_switch=@@optimizer_switch;
 set @@optimizer_switch='materialization=on,semijoin=off,partial_match_rowid_merge=on,partial_match_table_scan=off';
 
 create table t1 (a1 char(3) DEFAULT NULL, a2 char(3) DEFAULT NULL);
@@ -53,7 +50,6 @@ insert into t1 values (NULL, 'a21'), (NU
 explain select * from t1 where (a1, a2) not in (select a1, a2 from t1);
 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):
@@ -65,8 +61,52 @@ insert into t1 values ('t', '0'), ('0',
 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,semijoin=off';
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,semijoin=off';
 select * from t1 where (f1, f2) not in (select * from t2);
-set @@optimizer_switch=@save_optimizer_switch;
 drop table t1, t2;
+
+
+--echo #
+--echo # LP BUG#809245 Second assertion `bit < (map)->n_bits' with partial_match_merge
+--echo #
+
+CREATE TABLE t1 (d varchar(32)) ;
+INSERT INTO t1 VALUES ('r');
+
+CREATE TABLE t2 ( a int, c varchar(32)) ;
+INSERT INTO t2 VALUES (5,'r');
+
+CREATE TABLE t3 ( a int NOT NULL , d varchar(32)) ;
+INSERT INTO t3 VALUES (10,'g');
+
+set @@optimizer_switch='materialization=on,partial_match_rowid_merge=on,partial_match_table_scan=off,in_to_exists=off';
+
+EXPLAIN SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+        SELECT t3.d , t2.c
+        FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+
+SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+        SELECT t3.d , t2.c
+        FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+
+set @@optimizer_switch='materialization=off,in_to_exists=on';
+
+EXPLAIN SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+        SELECT t3.d , t2.c
+        FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+
+SELECT *
+FROM t1
+WHERE (t1.d , t1.d) NOT IN (
+        SELECT t3.d , t2.c
+        FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
+
+drop table t1, t2, t3;
+
+set @@optimizer_switch=@save_optimizer_switch;

=== modified file 'sql/item_subselect.cc'
--- a/sql/item_subselect.cc	2011-06-30 16:49:11 +0000
+++ b/sql/item_subselect.cc	2011-07-13 14:09:09 +0000
@@ -3864,8 +3864,7 @@ subselect_hash_sj_engine::get_strategy_u
       bitmap_set_bit(&non_null_key_parts, i);
       --count_partial_match_columns;
     }
-    if (result_sink->get_null_count_of_col(i) ==
-               tmp_table->file->stats.records)
+    if (result_sink->get_null_count_of_col(i) == tmp_table->file->stats.records)
       ++count_null_only_columns;
   }
 
@@ -5172,7 +5171,6 @@ void subselect_partial_match_engine::pri
 /*
   @param non_null_key_parts  
   @param partial_match_key_parts  A union of all single-column NULL key parts.
-  @param count_partial_match_columns Number of NULL keyparts (set bits above).
 
   @retval FALSE  the engine was initialized successfully
   @retval TRUE   there was some (memory allocation) error during initialization,
@@ -5189,24 +5187,24 @@ subselect_rowid_merge_engine::init(MY_BI
   rownum_t cur_rownum= 0;
   select_materialize_with_stats *result_sink=
     (select_materialize_with_stats *) result;
-  uint cur_keyid= 0;
+  uint cur_keyid;
   Item_in_subselect *item_in= (Item_in_subselect*) item;
   int error;
 
-  if (keys_count == 0)
+  if (merge_keys_count == 0)
   {
     /* There is nothing to initialize, we will only do regular lookups. */
     return FALSE;
   }
 
   DBUG_ASSERT(!covering_null_row_width || (covering_null_row_width &&
-                                           keys_count == 1 &&
+                                           merge_keys_count == 1 &&
                                            non_null_key_parts));
   /*
     Allocate buffers to hold the merged keys and the mapping between rowids and
     row numbers.
   */
-  if (!(merge_keys= (Ordered_key**) thd->alloc(keys_count *
+  if (!(merge_keys= (Ordered_key**) thd->alloc(merge_keys_count *
                                                sizeof(Ordered_key*))) ||
       !(row_num_to_rowid= (uchar*) my_malloc((size_t)(row_count * rowid_length),
         MYF(MY_WME))))
@@ -5215,14 +5213,16 @@ subselect_rowid_merge_engine::init(MY_BI
   /* Create the only non-NULL key if there is any. */
   if (non_null_key_parts)
   {
-    non_null_key= new Ordered_key(cur_keyid, tmp_table, item_in->left_expr,
+    non_null_key= new Ordered_key(0, tmp_table, item_in->left_expr,
                                   0, 0, 0, row_num_to_rowid);
     if (non_null_key->init(non_null_key_parts))
       return TRUE;
-    merge_keys[cur_keyid]= non_null_key;
-    merge_keys[cur_keyid]->first();
-    ++cur_keyid;
+    merge_keys[0]= non_null_key;
+    merge_keys[0]->first();
+    cur_keyid= 1;
   }
+  else
+    cur_keyid= 0;
 
   /*
     If there is a covering NULL row, the only key that is needed is the
@@ -5231,9 +5231,8 @@ subselect_rowid_merge_engine::init(MY_BI
   */
   if (!covering_null_row_width)
   {
-    if (bitmap_init_memroot(&matching_keys, keys_count, thd->mem_root) ||
-        bitmap_init_memroot(&matching_outer_cols, keys_count, thd->mem_root) ||
-        bitmap_init_memroot(&null_only_columns, keys_count, thd->mem_root))
+    if (bitmap_init_memroot(&matching_keys, merge_keys_count, thd->mem_root) ||
+        bitmap_init_memroot(&matching_outer_cols, merge_keys_count, thd->mem_root))
       return TRUE;
 
     /*
@@ -5242,31 +5241,25 @@ subselect_rowid_merge_engine::init(MY_BI
     */
     for (uint i= 0; i < partial_match_key_parts->n_bits; i++)
     {
-      if (!bitmap_is_set(partial_match_key_parts, i))
+      /* Skip columns that have no NULLs, or contain only NULLs. */
+      if (!bitmap_is_set(partial_match_key_parts, i) ||
+          result_sink->get_null_count_of_col(i) == row_count)
         continue;
 
-      if (result_sink->get_null_count_of_col(i) == row_count)
-      {
-        bitmap_set_bit(&null_only_columns, cur_keyid);
-        continue;
-      }
-      else
-      {
-        merge_keys[cur_keyid]= new Ordered_key(
+      merge_keys[cur_keyid]= new Ordered_key(
                                      cur_keyid, tmp_table,
                                      item_in->left_expr->element_index(i),
                                      result_sink->get_null_count_of_col(i),
                                      result_sink->get_min_null_of_col(i),
                                      result_sink->get_max_null_of_col(i),
                                      row_num_to_rowid);
-        if (merge_keys[cur_keyid]->init(i))
-          return TRUE;
-        merge_keys[cur_keyid]->first();
-      }
+      if (merge_keys[cur_keyid]->init(i))
+        return TRUE;
+      merge_keys[cur_keyid]->first();
       ++cur_keyid;
     }
   }
-  DBUG_ASSERT(cur_keyid == keys_count);
+  DBUG_ASSERT(cur_keyid == merge_keys_count);
 
   /* Populate the indexes with data from the temporary table. */
   if (tmp_table->file->ha_rnd_init_with_error(1))
@@ -5307,7 +5300,7 @@ subselect_rowid_merge_engine::init(MY_BI
       non_null_key->add_key(cur_rownum);
     }
 
-    for (uint i= (non_null_key ? 1 : 0); i < keys_count; i++)
+    for (uint i= (non_null_key ? 1 : 0); i < merge_keys_count; i++)
     {
       /*
         Check if the first and only indexed column contains NULL in the curent
@@ -5324,14 +5317,14 @@ subselect_rowid_merge_engine::init(MY_BI
   tmp_table->file->ha_rnd_end();
 
   /* Sort all the keys by their NULL selectivity. */
-  my_qsort(merge_keys, keys_count, sizeof(Ordered_key*),
+  my_qsort(merge_keys, merge_keys_count, sizeof(Ordered_key*),
            (qsort_cmp) cmp_keys_by_null_selectivity);
 
   /* Sort the keys in each of the indexes. */
-  for (uint i= 0; i < keys_count; i++)
+  for (uint i= 0; i < merge_keys_count; i++)
     merge_keys[i]->sort_keys();
 
-  if (init_queue(&pq, keys_count, 0, FALSE,
+  if (init_queue(&pq, merge_keys_count, 0, FALSE,
                  subselect_rowid_merge_engine::cmp_keys_by_cur_rownum, NULL,
                  0, 0))
     return TRUE;
@@ -5343,10 +5336,10 @@ subselect_rowid_merge_engine::init(MY_BI
 subselect_rowid_merge_engine::~subselect_rowid_merge_engine()
 {
   /* None of the resources below is allocated if there are no ordered keys. */
-  if (keys_count)
+  if (merge_keys_count)
   {
     my_free((char*) row_num_to_rowid, MYF(0));
-    for (uint i= 0; i < keys_count; i++)
+    for (uint i= 0; i < merge_keys_count; i++)
       delete merge_keys[i];
     delete_queue(&pq);
     if (tmp_table->file->inited == handler::RND)
@@ -5404,6 +5397,10 @@ subselect_rowid_merge_engine::cmp_keys_b
   Check if certain table row contains a NULL in all columns for which there is
   no match in the corresponding value index.
 
+  @note
+  There is no need to check the columns that contain only NULLs, because
+  those are guaranteed to match.
+
   @retval TRUE if a NULL row exists
   @retval FALSE otherwise
 */
@@ -5411,16 +5408,14 @@ subselect_rowid_merge_engine::cmp_keys_b
 bool subselect_rowid_merge_engine::test_null_row(rownum_t row_num)
 {
   Ordered_key *cur_key;
-  uint cur_id;
-  for (uint i = 0; i < keys_count; i++)
+  for (uint i = 0; i < merge_keys_count; i++)
   {
     cur_key= merge_keys[i];
-    cur_id= cur_key->get_keyid();
-    if (bitmap_is_set(&matching_keys, cur_id))
+    if (bitmap_is_set(&matching_keys, cur_key->get_keyid()))
     {
       /*
-        The key 'i' (with id 'cur_keyid') already matches a value in row 'row_num',
-        thus we skip it as it can't possibly match a NULL.
+        The key 'i' (with id 'cur_keyid') already matches a value in row
+        'row_num', thus we skip it as it can't possibly match a NULL.
       */
       continue;
     }
@@ -5481,7 +5476,7 @@ bool subselect_rowid_merge_engine::parti
     Do not add the non_null_key, since it was already processed above.
   */
   bitmap_clear_all(&matching_outer_cols);
-  for (uint i= test(non_null_key); i < keys_count; i++)
+  for (uint i= test(non_null_key); i < merge_keys_count; i++)
   {
     DBUG_ASSERT(merge_keys[i]->get_column_count() == 1);
     if (merge_keys[i]->get_search_key(0)->null_value)
@@ -5519,7 +5514,6 @@ bool subselect_rowid_merge_engine::parti
 
   min_key= (Ordered_key*) queue_remove_top(&pq);
   min_row_num= min_key->current();
-  bitmap_copy(&matching_keys, &null_only_columns);
   bitmap_set_bit(&matching_keys, min_key->get_keyid());
   bitmap_union(&matching_keys, &matching_outer_cols);
   if (min_key->next_same())
@@ -5555,7 +5549,6 @@ bool subselect_rowid_merge_engine::parti
       {
         min_key= cur_key;
         min_row_num= cur_row_num;
-        bitmap_copy(&matching_keys, &null_only_columns);
         bitmap_set_bit(&matching_keys, min_key->get_keyid());
         bitmap_union(&matching_keys, &matching_outer_cols);
       }

=== modified file 'sql/item_subselect.h'
--- a/sql/item_subselect.h	2011-06-21 13:00:41 +0000
+++ b/sql/item_subselect.h	2011-07-13 14:09:09 +0000
@@ -1192,11 +1192,6 @@ class subselect_rowid_merge_engine: publ
   */
   MY_BITMAP matching_outer_cols;
   /*
-    Columns that consist of only NULLs. Such columns match any value.
-    Computed once per query execution.
-  */
-  MY_BITMAP null_only_columns;
-  /*
     Indexes of row numbers, sorted by <column_value, row_number>. If an
     index may contain NULLs, the NULLs are stored efficiently in a bitmap.
 
@@ -1205,13 +1200,13 @@ class subselect_rowid_merge_engine: publ
     non-NULL columns, it is contained in keys[0].
   */
   Ordered_key **merge_keys;
-  /* The number of elements in keys. */
-  uint keys_count;
+  /* The number of elements in merge_keys. */
+  uint merge_keys_count;
   /*
     An index on all non-NULL columns of 'tmp_table'. The index has the
     logical form: <[v_i1 | ... | v_ik], rownum>. It allows to find the row
     number where the columns c_i1,...,c1_k contain the values v_i1,...,v_ik.
-    If such an index exists, it is always the first element of 'keys'.
+    If such an index exists, it is always the first element of 'merge_keys'.
   */
   Ordered_key *non_null_key;
   /*
@@ -1236,7 +1231,7 @@ class subselect_rowid_merge_engine: publ
 public:
   subselect_rowid_merge_engine(THD *thd_arg,
                                subselect_uniquesubquery_engine *engine_arg,
-                               TABLE *tmp_table_arg, uint keys_count_arg,
+                               TABLE *tmp_table_arg, uint merge_keys_count_arg,
                                uint covering_null_row_width_arg,
                                Item_subselect *item_arg,
                                select_result_interceptor *result_arg,
@@ -1244,7 +1239,7 @@ class subselect_rowid_merge_engine: publ
     :subselect_partial_match_engine(thd_arg, engine_arg, tmp_table_arg,
                                     item_arg, result_arg, equi_join_conds_arg,
                                     covering_null_row_width_arg),
-    keys_count(keys_count_arg), non_null_key(NULL)
+    merge_keys_count(merge_keys_count_arg), non_null_key(NULL)
   {}
   ~subselect_rowid_merge_engine();
   bool init(MY_BITMAP *non_null_key_parts, MY_BITMAP *partial_match_key_parts);

_______________________________________________
commits mailing list
commits@xxxxxxxxxxx
https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits

Follow ups