List:Commits« Previous MessageNext Message »
From:Jorgen Loland Date:October 17 2011 1:52pm
Subject:bzr push into mysql-trunk branch (jorgen.loland:3500 to 3501) Bug#13068506
View as plain text  
 3501 Jorgen Loland	2011-10-17
      Bug#13068506: QUERY WITH GROUP BY ON NON-AGGR COLUMN RETURNS 
                    WRONG RESULT
      
      Consider the query:
      
      SELECT (
        SELECT MAX( t2.i2 )
        FROM t3 RIGHT JOIN t2 ON ( t2.i3 = 2 )
        WHERE t2.i3 <> t1.i1
      ) AS field1
      FROM t1
      GROUP BY field1;
      
      In simplify_joins(), the optimizer checks if the outer join can
      be transformed to an inner join, and if the ON conditions 
      can be transformed to WHERE conditions. This can be done if 
      there are conditions that reject null-extended rows (extensions
      to t3 in the query above)
      
      To check that the inner tables does have a join match for all
      qualifying outer rows, not_null_tables() is called on the 
      conditions and if all inner tables will produce rows the join
      is transformed (see simplify_joins()):
      
      if (conds)
        not_null_tables= conds->not_null_tables();
      ...
      if (!table->outer_join || (used_tables & not_null_tables))
      {
        <transformation happens here>
      }
      
      In the query above, t3 has table->map=1 and t2 has 
      table->map=2. Thus, when processing t2 of the subselect,
      used_tables=1. The WHERE condition is not null-rejecting for
      table t3, so not_null_tables shold not have bit 0 set. But 
      it has.
      
      Item_outer_ref inherits not_null_tables() from Item_ref. 
      Table t1 has table->map=1 in the outer select, so when 
      not_null_tables() is called on the t1.i1 part of the <> 
      condition, the map of t1 is returned. The bug is that
      Item_outer_ref::not_null_tables() returns the map of the outer
      reference in the first place. It should return 0.
     @ mysql-test/r/join_outer.result
        Added test for 13068506
     @ mysql-test/r/join_outer_bka.result
        Added test for 13068506
     @ mysql-test/r/join_outer_bka_nixbnl.result
        Added test for 13068506
     @ mysql-test/t/join_outer.test
        Added test for 13068506
     @ sql/item.h
        Implement Item_outer_ref::not_null_tables()

    modified:
      mysql-test/r/join_outer.result
      mysql-test/r/join_outer_bka.result
      mysql-test/r/join_outer_bka_nixbnl.result
      mysql-test/t/join_outer.test
      sql/item.h
 3500 Marko Mäkelä	2011-10-17
      Fix a memory leak caused by faulty merge of Bug#13006367 fix.
      
      buf_pool_free_instance(): Restore the ha_clear() call.

    modified:
      storage/innobase/buf/buf0buf.c
=== modified file 'mysql-test/r/join_outer.result'
--- a/mysql-test/r/join_outer.result	2011-09-30 12:20:04 +0000
+++ b/mysql-test/r/join_outer.result	2011-10-17 13:52:27 +0000
@@ -1777,3 +1777,33 @@ WHERE t2.pk
 ORDER BY t2.col_int_key;
 col_int_key
 DROP TABLE t1,t2;
+#
+# Bug#13068506 - QUERY WITH GROUP BY ON NON-AGGR COLUMN RETURNS WRONG RESULT
+#
+CREATE TABLE t1 (i1 int);
+INSERT INTO t1 VALUES (100), (101);
+CREATE TABLE t2 (i2 int, i3 int);
+INSERT INTO t2 VALUES (20,1),(10,2);
+CREATE TABLE t3 (i4 int(11));
+INSERT INTO t3 VALUES (1),(2);
+
+SELECT (
+SELECT MAX( t2.i2 )
+FROM t3 RIGHT JOIN t2 ON ( t2.i3 = 2 )
+WHERE t2.i3 <> t1.i1
+) AS field1
+FROM t1;;
+field1
+20
+20
+
+SELECT (
+SELECT MAX( t2.i2 )
+FROM t3 RIGHT JOIN t2 ON ( t2.i3 = 2 )
+WHERE t2.i3 <> t1.i1
+) AS field1
+FROM t1 GROUP BY field1;;
+field1
+20
+
+drop table t1,t2,t3;

=== modified file 'mysql-test/r/join_outer_bka.result'
--- a/mysql-test/r/join_outer_bka.result	2011-10-05 13:16:38 +0000
+++ b/mysql-test/r/join_outer_bka.result	2011-10-17 13:52:27 +0000
@@ -1778,4 +1778,34 @@ WHERE t2.pk
 ORDER BY t2.col_int_key;
 col_int_key
 DROP TABLE t1,t2;
+#
+# Bug#13068506 - QUERY WITH GROUP BY ON NON-AGGR COLUMN RETURNS WRONG RESULT
+#
+CREATE TABLE t1 (i1 int);
+INSERT INTO t1 VALUES (100), (101);
+CREATE TABLE t2 (i2 int, i3 int);
+INSERT INTO t2 VALUES (20,1),(10,2);
+CREATE TABLE t3 (i4 int(11));
+INSERT INTO t3 VALUES (1),(2);
+
+SELECT (
+SELECT MAX( t2.i2 )
+FROM t3 RIGHT JOIN t2 ON ( t2.i3 = 2 )
+WHERE t2.i3 <> t1.i1
+) AS field1
+FROM t1;;
+field1
+20
+20
+
+SELECT (
+SELECT MAX( t2.i2 )
+FROM t3 RIGHT JOIN t2 ON ( t2.i3 = 2 )
+WHERE t2.i3 <> t1.i1
+) AS field1
+FROM t1 GROUP BY field1;;
+field1
+20
+
+drop table t1,t2,t3;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/join_outer_bka_nixbnl.result'
--- a/mysql-test/r/join_outer_bka_nixbnl.result	2011-10-05 13:16:38 +0000
+++ b/mysql-test/r/join_outer_bka_nixbnl.result	2011-10-17 13:52:27 +0000
@@ -1778,4 +1778,34 @@ WHERE t2.pk
 ORDER BY t2.col_int_key;
 col_int_key
 DROP TABLE t1,t2;
+#
+# Bug#13068506 - QUERY WITH GROUP BY ON NON-AGGR COLUMN RETURNS WRONG RESULT
+#
+CREATE TABLE t1 (i1 int);
+INSERT INTO t1 VALUES (100), (101);
+CREATE TABLE t2 (i2 int, i3 int);
+INSERT INTO t2 VALUES (20,1),(10,2);
+CREATE TABLE t3 (i4 int(11));
+INSERT INTO t3 VALUES (1),(2);
+
+SELECT (
+SELECT MAX( t2.i2 )
+FROM t3 RIGHT JOIN t2 ON ( t2.i3 = 2 )
+WHERE t2.i3 <> t1.i1
+) AS field1
+FROM t1;;
+field1
+20
+20
+
+SELECT (
+SELECT MAX( t2.i2 )
+FROM t3 RIGHT JOIN t2 ON ( t2.i3 = 2 )
+WHERE t2.i3 <> t1.i1
+) AS field1
+FROM t1 GROUP BY field1;;
+field1
+20
+
+drop table t1,t2,t3;
 set optimizer_switch=default;

=== modified file 'mysql-test/t/join_outer.test'
--- a/mysql-test/t/join_outer.test	2011-09-30 12:20:04 +0000
+++ b/mysql-test/t/join_outer.test	2011-10-17 13:52:27 +0000
@@ -1381,3 +1381,30 @@ WHERE t2.pk
 ORDER BY t2.col_int_key;
 
 DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug#13068506 - QUERY WITH GROUP BY ON NON-AGGR COLUMN RETURNS WRONG RESULT
+--echo #
+CREATE TABLE t1 (i1 int);
+INSERT INTO t1 VALUES (100), (101);
+
+CREATE TABLE t2 (i2 int, i3 int);
+INSERT INTO t2 VALUES (20,1),(10,2);
+
+CREATE TABLE t3 (i4 int(11));
+INSERT INTO t3 VALUES (1),(2);
+
+let $query= SELECT (
+  SELECT MAX( t2.i2 )
+  FROM t3 RIGHT JOIN t2 ON ( t2.i3 = 2 )
+  WHERE t2.i3 <> t1.i1
+) AS field1
+FROM t1;
+
+--echo
+--eval $query;
+--echo
+--eval $query GROUP BY field1;
+
+--echo
+drop table t1,t2,t3;

=== modified file 'sql/item.h'
--- a/sql/item.h	2011-10-13 12:33:08 +0000
+++ b/sql/item.h	2011-10-17 13:52:27 +0000
@@ -2830,6 +2830,8 @@ public:
   {
     return (*ref)->const_item() ? 0 : OUTER_REF_TABLE_BIT;
   }
+  table_map not_null_tables() const { return 0; }
+
   virtual Ref_Type ref_type() { return OUTER_REF; }
 };
 

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (jorgen.loland:3500 to 3501) Bug#13068506Jorgen Loland17 Oct