summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2013-08-29 12:32:09 -0700
committerIgor Babaev <igor@askmonty.org>2013-08-29 12:32:09 -0700
commit59af095da430d539333c404b9ee372fd414d6bd3 (patch)
tree878ec939c347031d30a180c63dca204863e85a99
parent28a9fea122e40bdb9f199f053cc70299656b7018 (diff)
parent37f18d2318c966b84a5e91a31c0985a9b2d0d9fd (diff)
downloadmariadb-git-59af095da430d539333c404b9ee372fd414d6bd3.tar.gz
Merge 5.3->5.5
-rw-r--r--mysql-test/r/join_outer.result26
-rw-r--r--mysql-test/r/join_outer_jcl6.result26
-rw-r--r--mysql-test/t/join_outer.test23
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/table.h10
5 files changed, 86 insertions, 1 deletions
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index 79ae845cacf..15890e546d2 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -2164,4 +2164,30 @@ SELECT * FROM t1 LEFT JOIN t2 ON a1 = a2
WHERE ( dt IS NULL OR FALSE ) AND b2 IS NULL;
a1 b1 dt a2 b2
DROP TABLE t1,t2;
+#
+# Bug mdev-4962: nested outer join with
+# <non-nullable datetime field> IS NULL in WHERE
+# causes an assert failure
+#
+CREATE TABLE t1 (i1 int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (i2 int) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (10),(20);
+CREATE TABLE t3 (i3 int, d3 datetime NOT NULL) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (8,'2008-12-04 17:53:42'),(9,'2012-12-21 12:12:12');
+SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON i2 = i3 ON i1 = i3
+WHERE d3 IS NULL;
+i1 i2 i3 d3
+1 NULL NULL NULL
+2 NULL NULL NULL
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON i2 = i3 ON i1 = i3
+WHERE d3 IS NULL;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t2`.`i2` AS `i2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`d3` AS `d3` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t2`.`i2` = `test`.`t1`.`i1`) and (`test`.`t3`.`i3` = `test`.`t1`.`i1`))) where ((`test`.`t3`.`d3` = 0) or isnull(`test`.`t3`.`d3`))
+DROP TABLE t1,t2,t3;
SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result
index c38fdc66974..7fda52931ca 100644
--- a/mysql-test/r/join_outer_jcl6.result
+++ b/mysql-test/r/join_outer_jcl6.result
@@ -2175,6 +2175,32 @@ SELECT * FROM t1 LEFT JOIN t2 ON a1 = a2
WHERE ( dt IS NULL OR FALSE ) AND b2 IS NULL;
a1 b1 dt a2 b2
DROP TABLE t1,t2;
+#
+# Bug mdev-4962: nested outer join with
+# <non-nullable datetime field> IS NULL in WHERE
+# causes an assert failure
+#
+CREATE TABLE t1 (i1 int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+CREATE TABLE t2 (i2 int) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (10),(20);
+CREATE TABLE t3 (i3 int, d3 datetime NOT NULL) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (8,'2008-12-04 17:53:42'),(9,'2012-12-21 12:12:12');
+SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON i2 = i3 ON i1 = i3
+WHERE d3 IS NULL;
+i1 i2 i3 d3
+1 NULL NULL NULL
+2 NULL NULL NULL
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON i2 = i3 ON i1 = i3
+WHERE d3 IS NULL;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00
+1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join)
+1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join)
+Warnings:
+Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t2`.`i2` AS `i2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`d3` AS `d3` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(((`test`.`t2`.`i2` = `test`.`t1`.`i1`) and (`test`.`t3`.`i3` = `test`.`t1`.`i1`))) where ((`test`.`t3`.`d3` = 0) or isnull(`test`.`t3`.`d3`))
+DROP TABLE t1,t2,t3;
SET optimizer_switch=@save_optimizer_switch;
set join_cache_level=default;
show variables like 'join_cache_level';
diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test
index 04bf09b7484..0eccb8e1587 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -1721,4 +1721,27 @@ SELECT * FROM t1 LEFT JOIN t2 ON a1 = a2
DROP TABLE t1,t2;
+--echo #
+--echo # Bug mdev-4962: nested outer join with
+--echo # <non-nullable datetime field> IS NULL in WHERE
+--echo # causes an assert failure
+--echo #
+
+CREATE TABLE t1 (i1 int) ENGINE=MyISAM;
+INSERT INTO t1 VALUES (1),(2);
+
+CREATE TABLE t2 (i2 int) ENGINE=MyISAM;
+INSERT INTO t2 VALUES (10),(20);
+
+CREATE TABLE t3 (i3 int, d3 datetime NOT NULL) ENGINE=MyISAM;
+INSERT INTO t3 VALUES (8,'2008-12-04 17:53:42'),(9,'2012-12-21 12:12:12');
+
+SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON i2 = i3 ON i1 = i3
+ WHERE d3 IS NULL;
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON i2 = i3 ON i1 = i3
+ WHERE d3 IS NULL;
+
+DROP TABLE t1,t2,t3;
+
SET optimizer_switch=@save_optimizer_switch;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index c959e1d1ce9..6ee81324867 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -13832,7 +13832,7 @@ internal_remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
if (!eq_cond)
return cond;
- if (field->table->pos_in_table_list->outer_join)
+ if (field->table->pos_in_table_list->is_inner_table_of_outer_join())
{
// outer join: transform "col IS NULL" to "col IS NULL or col=0"
Item *or_cond= new(thd->mem_root) Item_cond_or(eq_cond, cond);
diff --git a/sql/table.h b/sql/table.h
index cfdc0ffd077..7a946d63bcc 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -2129,6 +2129,16 @@ struct TABLE_LIST
bool single_table_updatable();
+ bool is_inner_table_of_outer_join()
+ {
+ for (TABLE_LIST *tbl= this; tbl; tbl= tbl->embedding)
+ {
+ if (tbl->outer_join)
+ return true;
+ }
+ return false;
+ }
+
private:
bool prep_check_option(THD *thd, uint8 check_opt_type);
bool prep_where(THD *thd, Item **conds, bool no_where_clause);