List:Commits« Previous MessageNext Message »
From:Sergey Petrunia Date:April 26 2008 4:09am
Subject:bk commit into 6.0 tree (sergefp:1.2627) BUG#33743
View as plain text  
Below is the list of changes that have just been committed into a local
6.0 repository of sergefp.  When sergefp does a push these changes
will be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2008-04-26 06:09:22+04:00, sergefp@stripped +5 -0
  BUG#33743 "nested subqueries, unique index, wrong result"
  Fix a lot of problems found by the NIST test:
  - sj_table_is_included(): Make the check if an sj-outer table is functionally 
    dependent on other sj-outer tables actually work: don't rely on 
    join_tab->ref.depend_map, it can be wrong because of equality propagation,
    do check tab->ref.items array instead.
  - setup_semijoin_dups_elimination(): 
    = Don't use InsideOut strategy if inner tables are interleaved with 
      outer (it is unusable)
    = When setting up FirstMatch strategy for a case with multiple inner 
      tables, set tab->do_firstmatch only for the last inner table.
  - get_bound_sj_equalities(): fix typo
  - best_access_path(): Don't consider InsideOut strategy when all subquery's
    outer references are bound.
    already bound.

  mysql-test/r/subselect.result@stripped, 2008-04-26 06:09:13+04:00, sergefp@stripped +1 -1
    BUG#33743 "nested subqueries, unique index, wrong result"
    - Update test results

  mysql-test/r/subselect_no_mat.result@stripped, 2008-04-26 06:09:13+04:00, sergefp@stripped
+1 -1
    BUG#33743 "nested subqueries, unique index, wrong result"
    - Update test results

  mysql-test/r/subselect_sj2.result@stripped, 2008-04-26 06:09:13+04:00, sergefp@stripped +89
-0
    BUG#33743 "nested subqueries, unique index, wrong result"
    - Testcase

  mysql-test/t/subselect_sj2.test@stripped, 2008-04-26 06:09:13+04:00, sergefp@stripped +88
-0
    BUG#33743 "nested subqueries, unique index, wrong result"
    - Testcase

  sql/sql_select.cc@stripped, 2008-04-26 06:09:13+04:00, sergefp@stripped +29 -13
    BUG#33743 "nested subqueries, unique index, wrong result"
    Fix a lot of problems found by the NIST test:
    - sj_table_is_included(): Make the check if an sj-outer table is functionally 
      dependent on other sj-outer tables actually work: don't rely on 
      join_tab->ref.depend_map, it can be wrong because of equality propagation,
      do check tab->ref.items array instead.
    - setup_semijoin_dups_elimination(): 
      = Don't use InsideOut strategy if inner tables are interleaved with 
        outer (it is unusable)
      = When setting up FirstMatch strategy for a case with multiple inner 
        tables, set tab->do_firstmatch only for the last inner table.
    - get_bound_sj_equalities(): fix typo
    - best_access_path(): Don't consider InsideOut strategy when all subquery's
      outer references are bound.
      already bound.

diff -Nrup a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
--- a/mysql-test/r/subselect.result	2008-04-23 17:13:08 +04:00
+++ b/mysql-test/r/subselect.result	2008-04-26 06:09:13 +04:00
@@ -1353,7 +1353,7 @@ a
 explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	PRIMARY	t2	index	a	a	5	NULL	4	100.00	Using index; Start temporary
-1	PRIMARY	t1	ref	a	a	5	test.t2.a	101	100.00	Using index; FirstMatch(t2)
+1	PRIMARY	t1	ref	a	a	5	test.t2.a	101	100.00	Using index
 1	PRIMARY	t3	index	a	a	5	NULL	3	100.00	Using where; Using index; End temporary; Using
join buffer
 Warnings:
 Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join
`test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t3`.`a` =
`test`.`t1`.`b`))
diff -Nrup a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result
--- a/mysql-test/r/subselect_no_mat.result	2008-04-23 17:13:08 +04:00
+++ b/mysql-test/r/subselect_no_mat.result	2008-04-26 06:09:13 +04:00
@@ -1357,7 +1357,7 @@ a
 explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
 1	PRIMARY	t2	index	a	a	5	NULL	4	100.00	Using index; Start temporary
-1	PRIMARY	t1	ref	a	a	5	test.t2.a	101	100.00	Using index; FirstMatch(t2)
+1	PRIMARY	t1	ref	a	a	5	test.t2.a	101	100.00	Using index
 1	PRIMARY	t3	index	a	a	5	NULL	3	100.00	Using where; Using index; End temporary; Using
join buffer
 Warnings:
 Note	1003	select `test`.`t2`.`a` AS `a` from `test`.`t2` semi join (`test`.`t1` join
`test`.`t3`) where ((`test`.`t1`.`a` = `test`.`t2`.`a`) and (`test`.`t3`.`a` =
`test`.`t1`.`b`))
diff -Nrup a/mysql-test/r/subselect_sj2.result b/mysql-test/r/subselect_sj2.result
--- a/mysql-test/r/subselect_sj2.result	2008-04-24 02:01:04 +04:00
+++ b/mysql-test/r/subselect_sj2.result	2008-04-26 06:09:13 +04:00
@@ -455,3 +455,92 @@ group by  t1.b);
 1
 1
 drop table t1;
+CREATE TABLE t1
+(EMPNUM   CHAR(3) NOT NULL,
+EMPNAME  CHAR(20),
+GRADE    DECIMAL(4),
+CITY     CHAR(15));
+CREATE TABLE t2
+(PNUM     CHAR(3) NOT NULL,
+PNAME    CHAR(20),
+PTYPE    CHAR(6),
+BUDGET   DECIMAL(9),
+CITY     CHAR(15));
+CREATE TABLE t3
+(EMPNUM   CHAR(3) NOT NULL,
+PNUM     CHAR(3) NOT NULL,
+HOURS    DECIMAL(5));
+INSERT INTO t1 VALUES ('E1','Alice',12,'Deale');
+INSERT INTO t1 VALUES ('E2','Betty',10,'Vienna');
+INSERT INTO t1 VALUES ('E3','Carmen',13,'Vienna');
+INSERT INTO t1 VALUES ('E4','Don',12,'Deale');
+INSERT INTO t1 VALUES ('E5','Ed',13,'Akron');
+INSERT INTO t2 VALUES ('P1','MXSS','Design',10000,'Deale');
+INSERT INTO t2 VALUES ('P2','CALM','Code',30000,'Vienna');
+INSERT INTO t2 VALUES ('P3','SDP','Test',30000,'Tampa');
+INSERT INTO t2 VALUES ('P4','SDP','Design',20000,'Deale');
+INSERT INTO t2 VALUES ('P5','IRM','Test',10000,'Vienna');
+INSERT INTO t2 VALUES ('P6','PAYR','Design',50000,'Deale');
+INSERT INTO t3 VALUES  ('E1','P1',40);
+INSERT INTO t3 VALUES  ('E1','P2',20);
+INSERT INTO t3 VALUES  ('E1','P3',80);
+INSERT INTO t3 VALUES  ('E1','P4',20);
+INSERT INTO t3 VALUES  ('E1','P5',12);
+INSERT INTO t3 VALUES  ('E1','P6',12);
+INSERT INTO t3 VALUES  ('E2','P1',40);
+INSERT INTO t3 VALUES  ('E2','P2',80);
+INSERT INTO t3 VALUES  ('E3','P2',20);
+INSERT INTO t3 VALUES  ('E4','P2',20);
+INSERT INTO t3 VALUES  ('E4','P4',40);
+INSERT INTO t3 VALUES  ('E4','P5',80);
+SELECT * FROM t1;
+EMPNUM	EMPNAME	GRADE	CITY
+E1	Alice	12	Deale
+E2	Betty	10	Vienna
+E3	Carmen	13	Vienna
+E4	Don	12	Deale
+E5	Ed	13	Akron
+CREATE UNIQUE INDEX t1_IDX ON t1(EMPNUM);
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+(SELECT EMPNUM
+FROM t3
+WHERE PNUM IN
+(SELECT PNUM
+FROM t2
+WHERE PTYPE = 'Design'));
+EMPNAME
+Alice
+Betty
+Don
+DROP INDEX t1_IDX ON t1;
+CREATE INDEX t1_IDX ON t1(EMPNUM);
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+(SELECT EMPNUM
+FROM t3
+WHERE PNUM IN
+(SELECT PNUM
+FROM t2
+WHERE PTYPE = 'Design'));
+EMPNAME
+Alice
+Betty
+Don
+DROP INDEX t1_IDX ON t1;
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+(SELECT EMPNUM
+FROM t3
+WHERE PNUM IN
+(SELECT PNUM
+FROM t2
+WHERE PTYPE = 'Design'));
+EMPNAME
+Alice
+Betty
+Don
+DROP TABLE t1, t2, t3;
diff -Nrup a/mysql-test/t/subselect_sj2.test b/mysql-test/t/subselect_sj2.test
--- a/mysql-test/t/subselect_sj2.test	2008-04-24 02:01:04 +04:00
+++ b/mysql-test/t/subselect_sj2.test	2008-04-26 06:09:13 +04:00
@@ -612,3 +612,91 @@ where t1.a not in (select 1 from t1 
                   group by  t1.b);
 drop table t1;
 
+#
+# BUG#33743 "nested subqueries, unique index, wrong result"
+#
+CREATE TABLE t1
+ (EMPNUM   CHAR(3) NOT NULL,
+  EMPNAME  CHAR(20),
+  GRADE    DECIMAL(4),
+  CITY     CHAR(15));
+
+CREATE TABLE t2
+ (PNUM     CHAR(3) NOT NULL,
+  PNAME    CHAR(20),
+  PTYPE    CHAR(6),
+  BUDGET   DECIMAL(9),
+  CITY     CHAR(15));
+
+CREATE TABLE t3
+ (EMPNUM   CHAR(3) NOT NULL,
+  PNUM     CHAR(3) NOT NULL,
+  HOURS    DECIMAL(5));
+
+INSERT INTO t1 VALUES ('E1','Alice',12,'Deale');
+INSERT INTO t1 VALUES ('E2','Betty',10,'Vienna');
+INSERT INTO t1 VALUES ('E3','Carmen',13,'Vienna');
+INSERT INTO t1 VALUES ('E4','Don',12,'Deale');
+INSERT INTO t1 VALUES ('E5','Ed',13,'Akron');
+
+INSERT INTO t2 VALUES ('P1','MXSS','Design',10000,'Deale');
+INSERT INTO t2 VALUES ('P2','CALM','Code',30000,'Vienna');
+INSERT INTO t2 VALUES ('P3','SDP','Test',30000,'Tampa');
+INSERT INTO t2 VALUES ('P4','SDP','Design',20000,'Deale');
+INSERT INTO t2 VALUES ('P5','IRM','Test',10000,'Vienna');
+INSERT INTO t2 VALUES ('P6','PAYR','Design',50000,'Deale');
+
+INSERT INTO t3 VALUES  ('E1','P1',40);
+INSERT INTO t3 VALUES  ('E1','P2',20);
+INSERT INTO t3 VALUES  ('E1','P3',80);
+INSERT INTO t3 VALUES  ('E1','P4',20);
+INSERT INTO t3 VALUES  ('E1','P5',12);
+INSERT INTO t3 VALUES  ('E1','P6',12);
+INSERT INTO t3 VALUES  ('E2','P1',40);
+INSERT INTO t3 VALUES  ('E2','P2',80);
+INSERT INTO t3 VALUES  ('E3','P2',20);
+INSERT INTO t3 VALUES  ('E4','P2',20);
+INSERT INTO t3 VALUES  ('E4','P4',40);
+INSERT INTO t3 VALUES  ('E4','P5',80);
+
+
+SELECT * FROM t1;
+CREATE UNIQUE INDEX t1_IDX ON t1(EMPNUM);
+--sorted_result
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+   (SELECT EMPNUM
+    FROM t3
+    WHERE PNUM IN
+       (SELECT PNUM
+        FROM t2
+        WHERE PTYPE = 'Design'));
+
+DROP INDEX t1_IDX ON t1;
+CREATE INDEX t1_IDX ON t1(EMPNUM);
+--sorted_result
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+   (SELECT EMPNUM
+    FROM t3
+    WHERE PNUM IN
+       (SELECT PNUM
+        FROM t2
+        WHERE PTYPE = 'Design'));
+
+DROP INDEX t1_IDX ON t1;
+--sorted_result
+SELECT EMPNAME
+FROM t1
+WHERE EMPNUM IN
+   (SELECT EMPNUM
+    FROM t3
+    WHERE PNUM IN
+       (SELECT PNUM
+        FROM t2
+        WHERE PTYPE = 'Design'));
+
+DROP TABLE t1, t2, t3;
+
diff -Nrup a/sql/sql_select.cc b/sql/sql_select.cc
--- a/sql/sql_select.cc	2008-04-25 03:59:32 +04:00
+++ b/sql/sql_select.cc	2008-04-26 06:09:13 +04:00
@@ -916,12 +916,17 @@ static bool sj_table_is_included(JOIN *j
   TABLE_LIST *embedding= join_tab->table->pos_in_table_list->embedding;
   if (join_tab->type == JT_EQ_REF)
   {
-    Table_map_iterator it(join_tab->ref.depend_map & ~PSEUDO_TABLE_BITS);
+    table_map depends_on= 0;
     uint idx;
+    
+    for (uint kp= 0; kp < join_tab->ref.key_parts; kp++)
+      depends_on |= join_tab->ref.items[kp]->used_tables();
+
+    Table_map_iterator it(depends_on & ~PSEUDO_TABLE_BITS);
     while ((idx= it.next_bit())!=Table_map_iterator::BITMAP_END)
     {
-      JOIN_TAB *ref_tab= join->join_tab + idx;
-      if (embedding == ref_tab->table->pos_in_table_list->embedding)
+      JOIN_TAB *ref_tab= join->map2table[idx];
+      if (embedding != ref_tab->table->pos_in_table_list->embedding)
         return TRUE;
     }
     /* Ok, functionally dependent */
@@ -1182,6 +1187,12 @@ int setup_semijoin_dups_elimination(JOIN
         dealing_with_jbuf= FALSE;
         dups_ranges[++cur_range].strategy= 0;
       }
+      else
+      {
+        /* We don't support interleaving for InsideOut*/
+        if (!tab->emb_sj_nest)
+          emb_insideout_nest= NULL;
+      }
     }
   }
 
@@ -1268,11 +1279,11 @@ int setup_semijoin_dups_elimination(JOIN
     /* Create the FirstMatch tail */
     for (; tab < join->join_tab + dups_ranges[j].end_idx; tab++)
     {
-      if (tab->emb_sj_nest)
-        tab->do_firstmatch= jump_to; 
-      else
+      if (!tab->emb_sj_nest)
         jump_to= tab;
     }
+    if (tab - 1 != jump_to)
+      tab[-1].do_firstmatch= jump_to;
   }
   DBUG_RETURN(FALSE);
 }
@@ -5308,7 +5319,7 @@ ulonglong get_bound_sj_equalities(TABLE_
     */
     if (!(item->used_tables() & remaining_tables))
     {
-      res |= 1ULL < i;
+      res |= 1ULL << i;
     }
   }
   return res;
@@ -5376,14 +5387,19 @@ best_access_path(JOIN      *join,
         3. We're not within a semi-join range (i.e. all semi-joins either have
            all or none of their tables in join_table_map), except
            s->emb_sj_nest (which we've just entered).
-        3. All correlation references from this sj-nest are bound
+        4. All non-IN-equality correlation references from this sj-nest are 
+           bound
+        5. But some of the IN-equalities aren't (so this can't be handled by 
+           FirstMatch strategy)
     */
-    if (s->emb_sj_nest &&                                                 //
(1)
+    if (s->emb_sj_nest &&                                               // (1)
         s->emb_sj_nest->sj_in_exprs < 64 && 
-        ((remaining_tables & s->emb_sj_nest->sj_inner_tables) ==           //
(2)
-         s->emb_sj_nest->sj_inner_tables) &&                              
// (2)
-        join->cur_emb_sj_nests == s->emb_sj_nest->sj_inner_tables &&    
  // (3)
-        !(remaining_tables & s->emb_sj_nest->nested_join->sj_corr_tables))
// (4)
+        ((remaining_tables & s->emb_sj_nest->sj_inner_tables) ==        // (2)
+         s->emb_sj_nest->sj_inner_tables) &&                            //
(2)
+        join->cur_emb_sj_nests == s->emb_sj_nest->sj_inner_tables &&   
// (3)
+        !(remaining_tables & 
+          s->emb_sj_nest->nested_join->sj_corr_tables) &&              
// (4)
+        remaining_tables & s->emb_sj_nest->nested_join->sj_depends_on)  //
(5)
     {
       /* This table is an InsideOut scan candidate */
       bound_sj_equalities= get_bound_sj_equalities(s->emb_sj_nest, 
Thread
bk commit into 6.0 tree (sergefp:1.2627) BUG#33743Sergey Petrunia26 Apr 2008