[Commits] bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (igor:2928) Bug#49322

Igor Babaev igor at askmonty.org
Fri Sep 10 07:16:10 EEST 2010


#At lp:maria based on revid:monty at askmonty.org-20100909151206-t637re7bm2fporr3

 2928 Igor Babaev	2010-09-09
      Fixed bug #49322.
      When not-exists optimization was applied to a table that
      happened to be an inner table of two outer joins, one
      embedded into another, then setting the match flag for
      the embedding outer join on could be skipped. This caused
      generation of extra null complemented rows.
      Made sure that the match flags are set correctly in all cases
      when not-exists optimization is used.  
      modified:
        mysql-test/r/join_nested.result
        mysql-test/t/join_nested.test
        sql/sql_select.cc

=== modified file 'mysql-test/r/join_nested.result'
--- a/mysql-test/r/join_nested.result	2007-07-13 14:36:10 +0000
+++ b/mysql-test/r/join_nested.result	2010-09-10 04:16:01 +0000
@@ -1743,4 +1743,62 @@ ON t4.carrier = t1.carrier;
 COUNT(*)
 6
 DROP TABLE t1,t2,t3,t4,t5;
+CREATE TABLE t1 (
+pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
+a int DEFAULT NULL,
+KEY idx(a)
+);
+CREATE TABLE t2 (
+pk int  NOT NULL AUTO_INCREMENT PRIMARY KEY,
+a int DEFAULT NULL,
+KEY idx(a)
+);
+CREATE TABLE t3 (
+pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
+a int DEFAULT NULL,
+KEY idx(a)
+);
+INSERT INTO t1 VALUES 
+(1,2), (2,7), (3,5), (4,7), (5,5), (6,NULL), (7,NULL), (8,9);
+INSERT INTO t2 VALUES 
+(1,NULL), (4,2), (5,2), (3,4), (2,8);
+INSERT INTO t3 VALUES
+(1,9), (2,2), (3,5), (4,2), (5,7), (6,0), (7,5);
+SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a 
+FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a;
+pk	a	pk	a	pk	a
+1	2	4	2	2	2
+1	2	4	2	4	2
+1	2	5	2	2	2
+1	2	5	2	4	2
+2	7	NULL	NULL	NULL	NULL
+3	5	NULL	NULL	NULL	NULL
+4	7	NULL	NULL	NULL	NULL
+5	5	NULL	NULL	NULL	NULL
+6	NULL	NULL	NULL	NULL	NULL
+7	NULL	NULL	NULL	NULL	NULL
+8	9	NULL	NULL	NULL	NULL
+SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a 
+FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a
+WHERE t2.pk IS NULL;
+pk	a	pk	a	pk	a
+2	7	NULL	NULL	NULL	NULL
+3	5	NULL	NULL	NULL	NULL
+4	7	NULL	NULL	NULL	NULL
+5	5	NULL	NULL	NULL	NULL
+6	NULL	NULL	NULL	NULL	NULL
+7	NULL	NULL	NULL	NULL	NULL
+8	9	NULL	NULL	NULL	NULL
+SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a 
+FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a
+WHERE t3.pk IS NULL;
+pk	a	pk	a	pk	a
+2	7	NULL	NULL	NULL	NULL
+3	5	NULL	NULL	NULL	NULL
+4	7	NULL	NULL	NULL	NULL
+5	5	NULL	NULL	NULL	NULL
+6	NULL	NULL	NULL	NULL	NULL
+7	NULL	NULL	NULL	NULL	NULL
+8	9	NULL	NULL	NULL	NULL
+DROP TABLE t1, t2, t3;
 End of 5.0 tests

=== modified file 'mysql-test/t/join_nested.test'
--- a/mysql-test/t/join_nested.test	2007-07-12 01:45:35 +0000
+++ b/mysql-test/t/join_nested.test	2010-09-10 04:16:01 +0000
@@ -1196,5 +1196,45 @@ SELECT COUNT(*) 
 
 DROP TABLE t1,t2,t3,t4,t5;
 
+#
+# BUG#49322: Nested left joins + not-exist optimization
+#
+
+CREATE TABLE t1 (
+  pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
+  a int DEFAULT NULL,
+  KEY idx(a)
+);
+CREATE TABLE t2 (
+  pk int  NOT NULL AUTO_INCREMENT PRIMARY KEY,
+  a int DEFAULT NULL,
+  KEY idx(a)
+);
+CREATE TABLE t3 (
+  pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
+  a int DEFAULT NULL,
+  KEY idx(a)
+);
+
+INSERT INTO t1 VALUES 
+  (1,2), (2,7), (3,5), (4,7), (5,5), (6,NULL), (7,NULL), (8,9);
+INSERT INTO t2 VALUES 
+  (1,NULL), (4,2), (5,2), (3,4), (2,8);
+INSERT INTO t3 VALUES
+  (1,9), (2,2), (3,5), (4,2), (5,7), (6,0), (7,5);
+
+SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a 
+  FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a;
+
+SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a 
+  FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a
+  WHERE t2.pk IS NULL;
+
+SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a 
+  FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a
+  WHERE t3.pk IS NULL;
+
+DROP TABLE t1, t2, t3;
+
 --echo End of 5.0 tests
 

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2010-09-03 16:20:30 +0000
+++ b/sql/sql_select.cc	2010-09-10 04:16:01 +0000
@@ -11738,6 +11738,7 @@ evaluate_join_record(JOIN *join, JOIN_TA
       condition is true => a match is found.
     */
     bool found= 1;
+    bool use_not_exists_opt= 0;
     while (join_tab->first_unmatched && found)
     {
       /*
@@ -11754,7 +11755,7 @@ evaluate_join_record(JOIN *join, JOIN_TA
       for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++)
       {
         if (tab->table->reginfo.not_exists_optimize)
-          return NESTED_LOOP_NO_MORE_ROWS;
+          use_not_exists_opt= 1;
         /* Check all predicates that has just been activated. */
         /*
           Actually all predicates non-guarded by first_unmatched->found
@@ -11787,6 +11788,9 @@ evaluate_join_record(JOIN *join, JOIN_TA
       join_tab->first_unmatched= first_unmatched;
     }
 
+    if (use_not_exists_opt)
+      return NESTED_LOOP_NO_MORE_ROWS;
+
     /*
       It was not just a return to lower loop level when one
       of the newly activated predicates is evaluated as false



More information about the commits mailing list